From 2f97e825cd9ab6a193772d8fbc719ae48c8fb8ef Mon Sep 17 00:00:00 2001 From: Miroslav Stastny Date: Fri, 4 Nov 2022 22:28:26 +0100 Subject: [PATCH 001/203] Enable build pipeline for web-components-v3 branch (#25529) * Enable build pipeline for web-components-v3 branch * Add comments --- azure-pipelines-pr.yml | 1 + azure-pipelines.bundlesize.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/azure-pipelines-pr.yml b/azure-pipelines-pr.yml index 50459ff3ee73f..fb1674dcb0345 100644 --- a/azure-pipelines-pr.yml +++ b/azure-pipelines-pr.yml @@ -1,5 +1,6 @@ pr: - master + - web-components-v3 # Remove before merging to master # There's a separate pipeline for CI which also uses this file, but with a trigger override in the UI # https://dev.azure.com/uifabric/fabricpublic/_apps/hub/ms.vss-ciworkflow.build-ci-hub?_a=edit-build-definition&id=164&view=Tab_Triggers diff --git a/azure-pipelines.bundlesize.yml b/azure-pipelines.bundlesize.yml index dda75d1e32a2b..ec3936c227e0f 100644 --- a/azure-pipelines.bundlesize.yml +++ b/azure-pipelines.bundlesize.yml @@ -1,5 +1,6 @@ pr: - master + - web-components-v3 # Remove before merging to master trigger: - master From 7bada17f646e03ad39e7917dee530cc32ea1a2f8 Mon Sep 17 00:00:00 2001 From: Miroslav Stastny Date: Mon, 7 Nov 2022 16:54:58 +0100 Subject: [PATCH 002/203] Enable bundle size pipeline on web-components-v3 branch (#25554) --- azure-pipelines.bundlesize.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/azure-pipelines.bundlesize.yml b/azure-pipelines.bundlesize.yml index ec3936c227e0f..fc845113a2abd 100644 --- a/azure-pipelines.bundlesize.yml +++ b/azure-pipelines.bundlesize.yml @@ -4,6 +4,7 @@ pr: trigger: - master + - web-components-v3 # Remove before merging to master variables: - ${{ if not(startsWith(variables['Build.SourceBranch'], 'refs/heads/')) }}: From 66d2d1caa4b309d699380acf78991976218dd87b Mon Sep 17 00:00:00 2001 From: Miroslav Stastny Date: Mon, 7 Nov 2022 18:01:06 +0100 Subject: [PATCH 003/203] Remove Web Components v2 implementation in v3 branch (#25434) * Delete existing Web Components implementation * Reset storybook * Change file * Add empty test to pass CI * Comment out WCs in stress-test --- ...-a9829849-1747-4588-aadf-da70207d0cf0.json | 7 + .../.storybook/preview-body.html | 12 - packages/web-components/.storybook/preview.js | 5 - packages/web-components/docs/api-report.md | 1724 +---------------- packages/web-components/public/switches.ts | 24 - .../web-components/src/__test__/setup-node.ts | 25 - .../design-system/color-explorer.stories.mdx | 16 - .../_docs/design-system/color-explorer/app.ts | 286 --- .../design-system/color-explorer/colors.ts | 25 - .../color-explorer/component-types.ts | 6 - .../color-explorer/components/color-block.ts | 438 ----- .../components/color-picker/README.md | 3 - .../color-picker.form-associated.ts | 15 - .../color-picker/color-picker.styles.ts | 132 -- .../color-picker/color-picker.template.ts | 134 -- .../components/color-picker/color-picker.ts | 377 ---- .../components/color-picker/index.ts | 16 - .../control-pane/control-pane.styles.ts | 20 - .../control-pane/control-pane.template.ts | 60 - .../components/control-pane/control-pane.ts | 20 - .../components/control-pane/index.ts | 14 - .../components/gradient/gradient.styles.ts | 32 - .../components/gradient/gradient.template.ts | 29 - .../components/gradient/gradient.ts | 10 - .../components/gradient/index.ts | 14 - .../components/layer-background/index.ts | 85 - .../components/sample-app/index.ts | 14 - .../sample-app/sample-app.styles.ts | 182 -- .../sample-app/sample-app.template.ts | 99 - .../components/sample-app/sample-app.ts | 3 - .../components/sample-page/index.ts | 14 - .../sample-page/sample-page.styles.ts | 131 -- .../sample-page/sample-page.template.ts | 83 - .../components/sample-page/sample-page.ts | 3 - .../color-explorer/components/swatch.ts | 182 -- .../color-explorer/custom-elements.ts | 5 - .../design-system/color-explorer/index.ts | 17 - .../design-system/design-tokens.stories.mdx | 216 --- .../design-system/high-contrast.stories.mdx | 185 -- .../getting-started/customization.stories.mdx | 238 --- .../getting-started/installation.stories.mdx | 70 - .../getting-started/overview.stories.mdx | 29 - .../_docs/integrations/angular.stories.mdx | 122 -- .../_docs/integrations/asp-net.stories.mdx | 89 - .../_docs/integrations/aurelia.stories.mdx | 291 --- .../src/_docs/integrations/blazor.stories.mdx | 118 -- .../src/_docs/integrations/ember.stories.mdx | 107 - .../integrations/introduction.stories.mdx | 18 - .../src/_docs/integrations/react.stories.mdx | 209 -- .../src/_docs/integrations/vue.stories.mdx | 97 - .../_docs/integrations/webpack.stories.mdx | 202 -- .../resources/browsersupport.stories.mdx | 19 - .../src/_docs/resources/faq.stories.mdx | 29 - .../src/_docs/resources/license.stories.mdx | 27 - .../src/_docs/resources/security.stories.mdx | 45 - .../accordion-item/accordion-item.styles.ts | 191 -- .../accordion-item.vscode.definition.json | 67 - .../src/accordion/accordion-item/index.ts | 35 - .../src/accordion/accordion.stories.ts | 71 - .../src/accordion/accordion.styles.ts | 18 - .../accordion.vscode.definition.json | 35 - .../src/accordion/fixtures/base.html | 46 - .../web-components/src/accordion/index.ts | 31 - .../src/anchor/anchor.stories.ts | 40 - .../src/anchor/anchor.styles.ts | 28 - .../src/anchor/anchor.vscode.definition.json | 138 -- .../src/anchor/fixtures/anchor.html | 131 -- packages/web-components/src/anchor/index.ts | 85 - .../anchored-region.stories.ts | 158 -- .../anchored-region/anchored-region.styles.ts | 12 - .../anchored-region.vscode.definition.json | 140 -- .../fixtures/anchored-region.html | 368 ---- .../src/anchored-region/fixtures/base.html | 389 ---- .../src/anchored-region/index.ts | 29 - .../web-components/src/badge/badge.stories.ts | 32 - .../web-components/src/badge/badge.styles.ts | 54 - .../src/badge/badge.vscode.definition.json | 60 - .../src/badge/fixtures/badge.html | 24 - packages/web-components/src/badge/index.ts | 48 - .../breadcrumb-item.stories.ts | 20 - .../breadcrumb-item/breadcrumb-item.styles.ts | 116 -- .../breadcrumb-item.vscode.definition.json | 50 - .../fixtures/breadcrumb-item.html | 37 - .../src/breadcrumb-item/index.ts | 37 - .../src/breadcrumb/breadcrumb.stories.ts | 24 - .../src/breadcrumb/breadcrumb.styles.ts | 17 - .../breadcrumb.vscode.definition.json | 18 - .../src/breadcrumb/fixtures/breadcrumb.html | 97 - .../web-components/src/breadcrumb/index.ts | 29 - .../src/button/button.stories.ts | 47 - .../src/button/button.styles.ts | 47 - .../src/button/button.vscode.definition.json | 158 -- .../src/button/fixtures/button.html | 117 -- packages/web-components/src/button/index.ts | 84 - .../src/calendar/calendar.stories.ts | 136 -- .../src/calendar/calendar.styles.ts | 162 -- .../calendar/calendar.vscode.definition.json | 156 -- packages/web-components/src/calendar/index.ts | 33 - packages/web-components/src/card/README.md | 34 - .../web-components/src/card/card.stories.ts | 35 - .../web-components/src/card/card.styles.ts | 48 - .../src/card/card.vscode.definition.json | 33 - .../src/card/fixtures/card.html | 123 -- packages/web-components/src/card/index.ts | 105 - .../src/checkbox/checkbox.stories.ts | 50 - .../src/checkbox/checkbox.styles.ts | 196 -- .../checkbox/checkbox.vscode.definition.json | 69 - .../src/checkbox/fixtures/checkbox.html | 43 - packages/web-components/src/checkbox/index.ts | 33 - packages/web-components/src/color/README.md | 32 - packages/web-components/src/color/palette.ts | 401 ---- packages/web-components/src/color/recipe.ts | 24 - .../recipes/contrast-and-delta-swatch-set.ts | 75 - .../src/color/recipes/contrast-swatch.spec.ts | 29 - .../src/color/recipes/contrast-swatch.ts | 15 - .../src/color/recipes/delta-swatch-set.ts | 95 - .../src/color/recipes/delta-swatch.ts | 16 - .../src/color/recipes/focus-stroke.ts | 18 - .../recipes/foreground-on-accent.spec.ts | 19 - .../src/color/recipes/foreground-on-accent.ts | 31 - .../color/recipes/gradient-shadow-stroke.ts | 78 - .../src/color/recipes/gradient-swatch.ts | 48 - .../src/color/recipes/neutral-layer-1.ts | 17 - .../src/color/recipes/neutral-layer-2.ts | 10 - .../src/color/recipes/neutral-layer-3.ts | 10 - .../src/color/recipes/neutral-layer-4.ts | 10 - .../color/recipes/neutral-layer-floating.ts | 10 - .../src/color/recipes/neutral-layer.spec.ts | 90 - .../src/color/recipes/underline-stroke.ts | 47 - packages/web-components/src/color/swatch.ts | 77 - .../color/utilities/base-layer-luminance.ts | 15 - .../src/color/utilities/binary-search.ts | 31 - .../src/color/utilities/color-constants.ts | 23 - .../color/utilities/direction-by-is-dark.ts | 9 - .../src/color/utilities/is-dark.ts | 20 - .../src/color/utilities/relative-luminance.ts | 19 - .../src/combobox/combobox.stories.ts | 89 - .../src/combobox/combobox.styles.ts | 50 - .../combobox/combobox.vscode.definition.json | 121 -- .../src/combobox/fixtures/base.html | 267 --- packages/web-components/src/combobox/index.ts | 85 - .../src/component-definitions.js | 84 - .../web-components/src/custom-elements.ts | 198 -- .../src/data-grid/data-grid-cell.styles.ts | 56 - .../data-grid-cell.vscode.definition.json | 34 - .../src/data-grid/data-grid-row.styles.ts | 37 - .../data-grid-row.vscode.definition.json | 34 - .../src/data-grid/data-grid.stories.ts | 452 ----- .../src/data-grid/data-grid.styles.ts | 13 - .../data-grid.vscode.definition.json | 34 - .../src/data-grid/fixtures/base.html | 55 - .../web-components/src/data-grid/index.ts | 74 - ...ign-system-provider.vscode.definition.json | 510 ----- .../src/design-system-provider/index.ts | 1079 ----------- packages/web-components/src/design-tokens.ts | 1271 ------------ .../src/dialog/dialog.stories.ts | 42 - .../src/dialog/dialog.styles.ts | 52 - .../src/dialog/dialog.vscode.definition.json | 67 - .../dialog/fixtures/dialog-button-test.html | 5 - .../src/dialog/fixtures/dialog.html | 5 - packages/web-components/src/dialog/index.ts | 29 - .../src/divider/divider.stories.ts | 46 - .../src/divider/divider.styles.ts | 23 - .../divider/divider.vscode.definition.json | 29 - .../src/divider/fixtures/divider.html | 6 - packages/web-components/src/divider/index.ts | 29 - packages/web-components/src/empty.spec.ts | 3 + .../src/flipper/fixtures/flipper.html | 33 - .../src/flipper/flipper.stories.ts | 38 - .../src/flipper/flipper.styles.ts | 110 -- .../flipper/flipper.vscode.definition.json | 56 - packages/web-components/src/flipper/index.ts | 39 - .../src/fluent-design-system.ts | 12 - .../fixtures/horizontal-scroll.html | 280 --- .../horizontal-scroll.stories.ts | 85 - .../horizontal-scroll.styles.ts | 145 -- .../horizontal-scroll.vscode.definition.json | 85 - .../src/horizontal-scroll/index.ts | 55 - packages/web-components/src/index-rollup.ts | 15 - packages/web-components/src/index.ts | 52 +- .../src/listbox-option/fixtures/base.html | 31 - .../src/listbox-option/index.ts | 24 - .../listbox-option/listbox-option.stories.ts | 44 - .../listbox-option/listbox-option.styles.ts | 170 -- .../listbox-option.vscode.definition.json | 45 - .../src/listbox/fixtures/base.html | 62 - packages/web-components/src/listbox/index.ts | 26 - .../src/listbox/listbox.stories.ts | 34 - .../src/listbox/listbox.styles.ts | 36 - .../listbox/listbox.vscode.definition.json | 40 - .../web-components/src/menu-item/README.md | 3 - .../src/menu-item/fixtures/menu-item.html | 75 - .../web-components/src/menu-item/index.ts | 44 - .../src/menu-item/menu-item.stories.ts | 40 - .../src/menu-item/menu-item.styles.ts | 293 --- .../menu-item.vscode.definition.json | 82 - packages/web-components/src/menu/README.md | 3 - .../src/menu/fixtures/menu.html | 192 -- packages/web-components/src/menu/index.ts | 40 - .../web-components/src/menu/menu.stories.ts | 61 - .../web-components/src/menu/menu.styles.ts | 57 - .../src/menu/menu.vscode.definition.json | 18 - .../number-field/fixtures/number-field.html | 109 -- .../web-components/src/number-field/index.ts | 77 - .../src/number-field/number-field.stories.ts | 103 - .../src/number-field/number-field.styles.ts | 92 - .../number-field.vscode.definition.json | 167 -- packages/web-components/src/progress/index.ts | 2 - .../progress-ring/fixtures/circular.html | 22 - .../src/progress/progress-ring/index.ts | 47 - .../progress-ring/progress-ring.stories.ts | 73 - .../progress-ring/progress-ring.styles.ts | 93 - .../progress-ring.vscode.definition.json | 56 - .../progress/progress/fixtures/linear.html | 24 - .../src/progress/progress/index.ts | 35 - .../src/progress/progress/progress.stories.ts | 73 - .../src/progress/progress/progress.styles.ts | 139 -- .../progress/progress.vscode.definition.json | 56 - .../src/radio-group/fixtures/radio-group.html | 76 - .../web-components/src/radio-group/index.ts | 29 - .../src/radio-group/radio-group.stories.ts | 48 - .../src/radio-group/radio-group.styles.ts | 25 - .../radio-group.vscode.definition.json | 64 - .../src/radio/fixtures/radio.html | 30 - packages/web-components/src/radio/index.ts | 34 - .../web-components/src/radio/radio.stories.ts | 47 - .../web-components/src/radio/radio.styles.ts | 186 -- .../src/radio/radio.vscode.definition.json | 63 - .../src/search/fixtures/search.html | 109 -- packages/web-components/src/search/index.ts | 56 - .../src/search/search.stories.ts | 104 - .../src/search/search.styles.ts | 135 -- .../src/search/search.template.ts | 94 - .../src/search/search.vscode.definition.json | 145 -- .../src/select/fixtures/base.html | 165 -- packages/web-components/src/select/index.ts | 79 - .../src/select/select.stories.ts | 58 - .../src/select/select.styles.ts | 181 -- .../src/select/select.vscode.definition.json | 79 - .../src/skeleton/fixtures/base.html | 65 - packages/web-components/src/skeleton/index.ts | 29 - .../src/skeleton/skeleton.stories.ts | 43 - .../src/skeleton/skeleton.styles.ts | 86 - .../skeleton/skeleton.vscode.definition.json | 49 - .../slider-label/fixtures/slider-label.html | 24 - .../web-components/src/slider-label/index.ts | 29 - .../src/slider-label/slider-label.stories.ts | 46 - .../src/slider-label/slider-label.styles.ts | 91 - .../slider-label.vscode.definition.json | 43 - .../src/slider/fixtures/slider.html | 169 -- packages/web-components/src/slider/index.ts | 32 - .../src/slider/slider.stories.ts | 46 - .../src/slider/slider.styles.ts | 194 -- .../src/slider/slider.vscode.definition.json | 101 - .../web-components/src/styles/direction.ts | 90 - .../web-components/src/styles/elevation.ts | 117 -- packages/web-components/src/styles/focus.ts | 23 - packages/web-components/src/styles/index.ts | 5 - .../src/styles/patterns/button.styles.ts | 538 ----- .../src/styles/patterns/index.ts | 3 - .../src/styles/patterns/input.styles.ts | 311 --- .../src/styles/patterns/type-ramp.ts | 104 - packages/web-components/src/styles/size.ts | 10 - .../src/switch/fixtures/switch.html | 42 - packages/web-components/src/switch/index.ts | 34 - .../src/switch/switch.stories.ts | 48 - .../src/switch/switch.styles.ts | 253 --- .../src/switch/switch.vscode.definition.json | 68 - .../src/tabs/fixtures/tabs.html | 76 - packages/web-components/src/tabs/index.ts | 32 - .../src/tabs/tab-panel/index.ts | 29 - .../src/tabs/tab-panel/tab-panel.styles.ts | 15 - .../tab-panel.vscode.definition.json | 17 - packages/web-components/src/tabs/tab/index.ts | 29 - .../web-components/src/tabs/tab/tab.styles.ts | 94 - .../src/tabs/tab/tab.vscode.definition.json | 17 - .../web-components/src/tabs/tabs.stories.ts | 111 -- .../web-components/src/tabs/tabs.styles.ts | 117 -- .../src/tabs/tabs.vscode.definition.json | 50 - .../src/text-area/fixtures/text-area.html | 99 - .../web-components/src/text-area/index.ts | 73 - .../src/text-area/text-area.stories.ts | 70 - .../src/text-area/text-area.styles.ts | 69 - .../text-area.vscode.definition.json | 141 -- .../src/text-field/fixtures/text-field.html | 109 -- .../web-components/src/text-field/index.ts | 73 - .../src/text-field/text-field.stories.ts | 110 -- .../src/text-field/text-field.styles.ts | 69 - .../text-field.vscode.definition.json | 150 -- .../src/toolbar/fixtures/toolbar.html | 255 --- packages/web-components/src/toolbar/index.ts | 24 - .../src/toolbar/toolbar.stories.ts | 11 - .../src/toolbar/toolbar.styles.ts | 88 - .../toolbar/toolbar.vscode.definition.json | 43 - .../src/tooltip/fixtures/tooltip.html | 115 -- packages/web-components/src/tooltip/index.ts | 34 - .../src/tooltip/tooltip.stories.ts | 40 - .../src/tooltip/tooltip.styles.ts | 127 -- .../tooltip/tooltip.vscode.definition.json | 56 - .../src/tree-item/fixtures/tree-item.html | 68 - .../web-components/src/tree-item/index.ts | 35 - .../src/tree-item/tree-item.stories.ts | 40 - .../src/tree-item/tree-item.styles.ts | 277 --- .../tree-item.vscode.definition.json | 63 - .../src/tree-view/fixtures/tree-view.html | 128 -- .../web-components/src/tree-view/index.ts | 30 - .../src/tree-view/tree-view.stories.ts | 105 - .../src/tree-view/tree-view.styles.ts | 18 - .../tree-view.vscode.definition.json | 26 - .../web-components/src/utilities/behaviors.ts | 15 - .../web-components/src/utilities/type-ramp.ts | 12 - 311 files changed, 12 insertions(+), 28146 deletions(-) create mode 100644 change/@fluentui-web-components-a9829849-1747-4588-aadf-da70207d0cf0.json delete mode 100644 packages/web-components/.storybook/preview-body.html delete mode 100644 packages/web-components/public/switches.ts delete mode 100644 packages/web-components/src/__test__/setup-node.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer.stories.mdx delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/app.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/colors.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/component-types.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/color-block.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/README.md delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.form-associated.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.styles.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.template.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/index.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/control-pane.styles.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/control-pane.template.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/control-pane.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/index.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/gradient/gradient.styles.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/gradient/gradient.template.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/gradient/gradient.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/gradient/index.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/layer-background/index.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/index.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/sample-app.styles.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/sample-app.template.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/sample-app.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/index.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/sample-page.styles.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/sample-page.template.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/sample-page.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/components/swatch.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/custom-elements.ts delete mode 100644 packages/web-components/src/_docs/design-system/color-explorer/index.ts delete mode 100644 packages/web-components/src/_docs/design-system/design-tokens.stories.mdx delete mode 100644 packages/web-components/src/_docs/design-system/high-contrast.stories.mdx delete mode 100644 packages/web-components/src/_docs/getting-started/customization.stories.mdx delete mode 100644 packages/web-components/src/_docs/getting-started/installation.stories.mdx delete mode 100644 packages/web-components/src/_docs/getting-started/overview.stories.mdx delete mode 100644 packages/web-components/src/_docs/integrations/angular.stories.mdx delete mode 100644 packages/web-components/src/_docs/integrations/asp-net.stories.mdx delete mode 100644 packages/web-components/src/_docs/integrations/aurelia.stories.mdx delete mode 100644 packages/web-components/src/_docs/integrations/blazor.stories.mdx delete mode 100644 packages/web-components/src/_docs/integrations/ember.stories.mdx delete mode 100644 packages/web-components/src/_docs/integrations/introduction.stories.mdx delete mode 100644 packages/web-components/src/_docs/integrations/react.stories.mdx delete mode 100644 packages/web-components/src/_docs/integrations/vue.stories.mdx delete mode 100644 packages/web-components/src/_docs/integrations/webpack.stories.mdx delete mode 100644 packages/web-components/src/_docs/resources/browsersupport.stories.mdx delete mode 100644 packages/web-components/src/_docs/resources/faq.stories.mdx delete mode 100644 packages/web-components/src/_docs/resources/license.stories.mdx delete mode 100644 packages/web-components/src/_docs/resources/security.stories.mdx delete mode 100644 packages/web-components/src/accordion/accordion-item/accordion-item.styles.ts delete mode 100644 packages/web-components/src/accordion/accordion-item/accordion-item.vscode.definition.json delete mode 100644 packages/web-components/src/accordion/accordion-item/index.ts delete mode 100644 packages/web-components/src/accordion/accordion.stories.ts delete mode 100644 packages/web-components/src/accordion/accordion.styles.ts delete mode 100644 packages/web-components/src/accordion/accordion.vscode.definition.json delete mode 100644 packages/web-components/src/accordion/fixtures/base.html delete mode 100644 packages/web-components/src/accordion/index.ts delete mode 100644 packages/web-components/src/anchor/anchor.stories.ts delete mode 100644 packages/web-components/src/anchor/anchor.styles.ts delete mode 100644 packages/web-components/src/anchor/anchor.vscode.definition.json delete mode 100644 packages/web-components/src/anchor/fixtures/anchor.html delete mode 100644 packages/web-components/src/anchor/index.ts delete mode 100644 packages/web-components/src/anchored-region/anchored-region.stories.ts delete mode 100644 packages/web-components/src/anchored-region/anchored-region.styles.ts delete mode 100644 packages/web-components/src/anchored-region/anchored-region.vscode.definition.json delete mode 100644 packages/web-components/src/anchored-region/fixtures/anchored-region.html delete mode 100644 packages/web-components/src/anchored-region/fixtures/base.html delete mode 100644 packages/web-components/src/anchored-region/index.ts delete mode 100644 packages/web-components/src/badge/badge.stories.ts delete mode 100644 packages/web-components/src/badge/badge.styles.ts delete mode 100644 packages/web-components/src/badge/badge.vscode.definition.json delete mode 100644 packages/web-components/src/badge/fixtures/badge.html delete mode 100644 packages/web-components/src/badge/index.ts delete mode 100644 packages/web-components/src/breadcrumb-item/breadcrumb-item.stories.ts delete mode 100644 packages/web-components/src/breadcrumb-item/breadcrumb-item.styles.ts delete mode 100644 packages/web-components/src/breadcrumb-item/breadcrumb-item.vscode.definition.json delete mode 100644 packages/web-components/src/breadcrumb-item/fixtures/breadcrumb-item.html delete mode 100644 packages/web-components/src/breadcrumb-item/index.ts delete mode 100644 packages/web-components/src/breadcrumb/breadcrumb.stories.ts delete mode 100644 packages/web-components/src/breadcrumb/breadcrumb.styles.ts delete mode 100644 packages/web-components/src/breadcrumb/breadcrumb.vscode.definition.json delete mode 100644 packages/web-components/src/breadcrumb/fixtures/breadcrumb.html delete mode 100644 packages/web-components/src/breadcrumb/index.ts delete mode 100644 packages/web-components/src/button/button.stories.ts delete mode 100644 packages/web-components/src/button/button.styles.ts delete mode 100644 packages/web-components/src/button/button.vscode.definition.json delete mode 100644 packages/web-components/src/button/fixtures/button.html delete mode 100644 packages/web-components/src/button/index.ts delete mode 100644 packages/web-components/src/calendar/calendar.stories.ts delete mode 100644 packages/web-components/src/calendar/calendar.styles.ts delete mode 100644 packages/web-components/src/calendar/calendar.vscode.definition.json delete mode 100644 packages/web-components/src/calendar/index.ts delete mode 100644 packages/web-components/src/card/README.md delete mode 100644 packages/web-components/src/card/card.stories.ts delete mode 100644 packages/web-components/src/card/card.styles.ts delete mode 100644 packages/web-components/src/card/card.vscode.definition.json delete mode 100644 packages/web-components/src/card/fixtures/card.html delete mode 100644 packages/web-components/src/card/index.ts delete mode 100644 packages/web-components/src/checkbox/checkbox.stories.ts delete mode 100644 packages/web-components/src/checkbox/checkbox.styles.ts delete mode 100644 packages/web-components/src/checkbox/checkbox.vscode.definition.json delete mode 100644 packages/web-components/src/checkbox/fixtures/checkbox.html delete mode 100644 packages/web-components/src/checkbox/index.ts delete mode 100644 packages/web-components/src/color/README.md delete mode 100644 packages/web-components/src/color/palette.ts delete mode 100644 packages/web-components/src/color/recipe.ts delete mode 100644 packages/web-components/src/color/recipes/contrast-and-delta-swatch-set.ts delete mode 100644 packages/web-components/src/color/recipes/contrast-swatch.spec.ts delete mode 100644 packages/web-components/src/color/recipes/contrast-swatch.ts delete mode 100644 packages/web-components/src/color/recipes/delta-swatch-set.ts delete mode 100644 packages/web-components/src/color/recipes/delta-swatch.ts delete mode 100644 packages/web-components/src/color/recipes/focus-stroke.ts delete mode 100644 packages/web-components/src/color/recipes/foreground-on-accent.spec.ts delete mode 100644 packages/web-components/src/color/recipes/foreground-on-accent.ts delete mode 100644 packages/web-components/src/color/recipes/gradient-shadow-stroke.ts delete mode 100644 packages/web-components/src/color/recipes/gradient-swatch.ts delete mode 100644 packages/web-components/src/color/recipes/neutral-layer-1.ts delete mode 100644 packages/web-components/src/color/recipes/neutral-layer-2.ts delete mode 100644 packages/web-components/src/color/recipes/neutral-layer-3.ts delete mode 100644 packages/web-components/src/color/recipes/neutral-layer-4.ts delete mode 100644 packages/web-components/src/color/recipes/neutral-layer-floating.ts delete mode 100644 packages/web-components/src/color/recipes/neutral-layer.spec.ts delete mode 100644 packages/web-components/src/color/recipes/underline-stroke.ts delete mode 100644 packages/web-components/src/color/swatch.ts delete mode 100644 packages/web-components/src/color/utilities/base-layer-luminance.ts delete mode 100644 packages/web-components/src/color/utilities/binary-search.ts delete mode 100644 packages/web-components/src/color/utilities/color-constants.ts delete mode 100644 packages/web-components/src/color/utilities/direction-by-is-dark.ts delete mode 100644 packages/web-components/src/color/utilities/is-dark.ts delete mode 100644 packages/web-components/src/color/utilities/relative-luminance.ts delete mode 100644 packages/web-components/src/combobox/combobox.stories.ts delete mode 100644 packages/web-components/src/combobox/combobox.styles.ts delete mode 100644 packages/web-components/src/combobox/combobox.vscode.definition.json delete mode 100644 packages/web-components/src/combobox/fixtures/base.html delete mode 100644 packages/web-components/src/combobox/index.ts delete mode 100644 packages/web-components/src/component-definitions.js delete mode 100644 packages/web-components/src/custom-elements.ts delete mode 100644 packages/web-components/src/data-grid/data-grid-cell.styles.ts delete mode 100644 packages/web-components/src/data-grid/data-grid-cell.vscode.definition.json delete mode 100644 packages/web-components/src/data-grid/data-grid-row.styles.ts delete mode 100644 packages/web-components/src/data-grid/data-grid-row.vscode.definition.json delete mode 100644 packages/web-components/src/data-grid/data-grid.stories.ts delete mode 100644 packages/web-components/src/data-grid/data-grid.styles.ts delete mode 100644 packages/web-components/src/data-grid/data-grid.vscode.definition.json delete mode 100644 packages/web-components/src/data-grid/fixtures/base.html delete mode 100644 packages/web-components/src/data-grid/index.ts delete mode 100644 packages/web-components/src/design-system-provider/design-system-provider.vscode.definition.json delete mode 100644 packages/web-components/src/design-system-provider/index.ts delete mode 100644 packages/web-components/src/design-tokens.ts delete mode 100644 packages/web-components/src/dialog/dialog.stories.ts delete mode 100644 packages/web-components/src/dialog/dialog.styles.ts delete mode 100644 packages/web-components/src/dialog/dialog.vscode.definition.json delete mode 100644 packages/web-components/src/dialog/fixtures/dialog-button-test.html delete mode 100644 packages/web-components/src/dialog/fixtures/dialog.html delete mode 100644 packages/web-components/src/dialog/index.ts delete mode 100644 packages/web-components/src/divider/divider.stories.ts delete mode 100644 packages/web-components/src/divider/divider.styles.ts delete mode 100644 packages/web-components/src/divider/divider.vscode.definition.json delete mode 100644 packages/web-components/src/divider/fixtures/divider.html delete mode 100644 packages/web-components/src/divider/index.ts create mode 100644 packages/web-components/src/empty.spec.ts delete mode 100644 packages/web-components/src/flipper/fixtures/flipper.html delete mode 100644 packages/web-components/src/flipper/flipper.stories.ts delete mode 100644 packages/web-components/src/flipper/flipper.styles.ts delete mode 100644 packages/web-components/src/flipper/flipper.vscode.definition.json delete mode 100644 packages/web-components/src/flipper/index.ts delete mode 100644 packages/web-components/src/fluent-design-system.ts delete mode 100644 packages/web-components/src/horizontal-scroll/fixtures/horizontal-scroll.html delete mode 100644 packages/web-components/src/horizontal-scroll/horizontal-scroll.stories.ts delete mode 100644 packages/web-components/src/horizontal-scroll/horizontal-scroll.styles.ts delete mode 100644 packages/web-components/src/horizontal-scroll/horizontal-scroll.vscode.definition.json delete mode 100644 packages/web-components/src/horizontal-scroll/index.ts delete mode 100644 packages/web-components/src/listbox-option/fixtures/base.html delete mode 100644 packages/web-components/src/listbox-option/index.ts delete mode 100644 packages/web-components/src/listbox-option/listbox-option.stories.ts delete mode 100644 packages/web-components/src/listbox-option/listbox-option.styles.ts delete mode 100644 packages/web-components/src/listbox-option/listbox-option.vscode.definition.json delete mode 100644 packages/web-components/src/listbox/fixtures/base.html delete mode 100644 packages/web-components/src/listbox/index.ts delete mode 100644 packages/web-components/src/listbox/listbox.stories.ts delete mode 100644 packages/web-components/src/listbox/listbox.styles.ts delete mode 100644 packages/web-components/src/listbox/listbox.vscode.definition.json delete mode 100644 packages/web-components/src/menu-item/README.md delete mode 100644 packages/web-components/src/menu-item/fixtures/menu-item.html delete mode 100644 packages/web-components/src/menu-item/index.ts delete mode 100644 packages/web-components/src/menu-item/menu-item.stories.ts delete mode 100644 packages/web-components/src/menu-item/menu-item.styles.ts delete mode 100644 packages/web-components/src/menu-item/menu-item.vscode.definition.json delete mode 100644 packages/web-components/src/menu/README.md delete mode 100644 packages/web-components/src/menu/fixtures/menu.html delete mode 100644 packages/web-components/src/menu/index.ts delete mode 100644 packages/web-components/src/menu/menu.stories.ts delete mode 100644 packages/web-components/src/menu/menu.styles.ts delete mode 100644 packages/web-components/src/menu/menu.vscode.definition.json delete mode 100644 packages/web-components/src/number-field/fixtures/number-field.html delete mode 100644 packages/web-components/src/number-field/index.ts delete mode 100644 packages/web-components/src/number-field/number-field.stories.ts delete mode 100644 packages/web-components/src/number-field/number-field.styles.ts delete mode 100644 packages/web-components/src/number-field/number-field.vscode.definition.json delete mode 100644 packages/web-components/src/progress/index.ts delete mode 100644 packages/web-components/src/progress/progress-ring/fixtures/circular.html delete mode 100644 packages/web-components/src/progress/progress-ring/index.ts delete mode 100644 packages/web-components/src/progress/progress-ring/progress-ring.stories.ts delete mode 100644 packages/web-components/src/progress/progress-ring/progress-ring.styles.ts delete mode 100644 packages/web-components/src/progress/progress-ring/progress-ring.vscode.definition.json delete mode 100644 packages/web-components/src/progress/progress/fixtures/linear.html delete mode 100644 packages/web-components/src/progress/progress/index.ts delete mode 100644 packages/web-components/src/progress/progress/progress.stories.ts delete mode 100644 packages/web-components/src/progress/progress/progress.styles.ts delete mode 100644 packages/web-components/src/progress/progress/progress.vscode.definition.json delete mode 100644 packages/web-components/src/radio-group/fixtures/radio-group.html delete mode 100644 packages/web-components/src/radio-group/index.ts delete mode 100644 packages/web-components/src/radio-group/radio-group.stories.ts delete mode 100644 packages/web-components/src/radio-group/radio-group.styles.ts delete mode 100644 packages/web-components/src/radio-group/radio-group.vscode.definition.json delete mode 100644 packages/web-components/src/radio/fixtures/radio.html delete mode 100644 packages/web-components/src/radio/index.ts delete mode 100644 packages/web-components/src/radio/radio.stories.ts delete mode 100644 packages/web-components/src/radio/radio.styles.ts delete mode 100644 packages/web-components/src/radio/radio.vscode.definition.json delete mode 100644 packages/web-components/src/search/fixtures/search.html delete mode 100644 packages/web-components/src/search/index.ts delete mode 100644 packages/web-components/src/search/search.stories.ts delete mode 100644 packages/web-components/src/search/search.styles.ts delete mode 100644 packages/web-components/src/search/search.template.ts delete mode 100644 packages/web-components/src/search/search.vscode.definition.json delete mode 100644 packages/web-components/src/select/fixtures/base.html delete mode 100644 packages/web-components/src/select/index.ts delete mode 100644 packages/web-components/src/select/select.stories.ts delete mode 100644 packages/web-components/src/select/select.styles.ts delete mode 100644 packages/web-components/src/select/select.vscode.definition.json delete mode 100644 packages/web-components/src/skeleton/fixtures/base.html delete mode 100644 packages/web-components/src/skeleton/index.ts delete mode 100644 packages/web-components/src/skeleton/skeleton.stories.ts delete mode 100644 packages/web-components/src/skeleton/skeleton.styles.ts delete mode 100644 packages/web-components/src/skeleton/skeleton.vscode.definition.json delete mode 100644 packages/web-components/src/slider-label/fixtures/slider-label.html delete mode 100644 packages/web-components/src/slider-label/index.ts delete mode 100644 packages/web-components/src/slider-label/slider-label.stories.ts delete mode 100644 packages/web-components/src/slider-label/slider-label.styles.ts delete mode 100644 packages/web-components/src/slider-label/slider-label.vscode.definition.json delete mode 100644 packages/web-components/src/slider/fixtures/slider.html delete mode 100644 packages/web-components/src/slider/index.ts delete mode 100644 packages/web-components/src/slider/slider.stories.ts delete mode 100644 packages/web-components/src/slider/slider.styles.ts delete mode 100644 packages/web-components/src/slider/slider.vscode.definition.json delete mode 100644 packages/web-components/src/styles/direction.ts delete mode 100644 packages/web-components/src/styles/elevation.ts delete mode 100644 packages/web-components/src/styles/focus.ts delete mode 100644 packages/web-components/src/styles/index.ts delete mode 100644 packages/web-components/src/styles/patterns/button.styles.ts delete mode 100644 packages/web-components/src/styles/patterns/index.ts delete mode 100644 packages/web-components/src/styles/patterns/input.styles.ts delete mode 100644 packages/web-components/src/styles/patterns/type-ramp.ts delete mode 100644 packages/web-components/src/styles/size.ts delete mode 100644 packages/web-components/src/switch/fixtures/switch.html delete mode 100644 packages/web-components/src/switch/index.ts delete mode 100644 packages/web-components/src/switch/switch.stories.ts delete mode 100644 packages/web-components/src/switch/switch.styles.ts delete mode 100644 packages/web-components/src/switch/switch.vscode.definition.json delete mode 100644 packages/web-components/src/tabs/fixtures/tabs.html delete mode 100644 packages/web-components/src/tabs/index.ts delete mode 100644 packages/web-components/src/tabs/tab-panel/index.ts delete mode 100644 packages/web-components/src/tabs/tab-panel/tab-panel.styles.ts delete mode 100644 packages/web-components/src/tabs/tab-panel/tab-panel.vscode.definition.json delete mode 100644 packages/web-components/src/tabs/tab/index.ts delete mode 100644 packages/web-components/src/tabs/tab/tab.styles.ts delete mode 100644 packages/web-components/src/tabs/tab/tab.vscode.definition.json delete mode 100644 packages/web-components/src/tabs/tabs.stories.ts delete mode 100644 packages/web-components/src/tabs/tabs.styles.ts delete mode 100644 packages/web-components/src/tabs/tabs.vscode.definition.json delete mode 100644 packages/web-components/src/text-area/fixtures/text-area.html delete mode 100644 packages/web-components/src/text-area/index.ts delete mode 100644 packages/web-components/src/text-area/text-area.stories.ts delete mode 100644 packages/web-components/src/text-area/text-area.styles.ts delete mode 100644 packages/web-components/src/text-area/text-area.vscode.definition.json delete mode 100644 packages/web-components/src/text-field/fixtures/text-field.html delete mode 100644 packages/web-components/src/text-field/index.ts delete mode 100644 packages/web-components/src/text-field/text-field.stories.ts delete mode 100644 packages/web-components/src/text-field/text-field.styles.ts delete mode 100644 packages/web-components/src/text-field/text-field.vscode.definition.json delete mode 100644 packages/web-components/src/toolbar/fixtures/toolbar.html delete mode 100644 packages/web-components/src/toolbar/index.ts delete mode 100644 packages/web-components/src/toolbar/toolbar.stories.ts delete mode 100644 packages/web-components/src/toolbar/toolbar.styles.ts delete mode 100644 packages/web-components/src/toolbar/toolbar.vscode.definition.json delete mode 100644 packages/web-components/src/tooltip/fixtures/tooltip.html delete mode 100644 packages/web-components/src/tooltip/index.ts delete mode 100644 packages/web-components/src/tooltip/tooltip.stories.ts delete mode 100644 packages/web-components/src/tooltip/tooltip.styles.ts delete mode 100644 packages/web-components/src/tooltip/tooltip.vscode.definition.json delete mode 100644 packages/web-components/src/tree-item/fixtures/tree-item.html delete mode 100644 packages/web-components/src/tree-item/index.ts delete mode 100644 packages/web-components/src/tree-item/tree-item.stories.ts delete mode 100644 packages/web-components/src/tree-item/tree-item.styles.ts delete mode 100644 packages/web-components/src/tree-item/tree-item.vscode.definition.json delete mode 100644 packages/web-components/src/tree-view/fixtures/tree-view.html delete mode 100644 packages/web-components/src/tree-view/index.ts delete mode 100644 packages/web-components/src/tree-view/tree-view.stories.ts delete mode 100644 packages/web-components/src/tree-view/tree-view.styles.ts delete mode 100644 packages/web-components/src/tree-view/tree-view.vscode.definition.json delete mode 100644 packages/web-components/src/utilities/behaviors.ts delete mode 100644 packages/web-components/src/utilities/type-ramp.ts diff --git a/change/@fluentui-web-components-a9829849-1747-4588-aadf-da70207d0cf0.json b/change/@fluentui-web-components-a9829849-1747-4588-aadf-da70207d0cf0.json new file mode 100644 index 0000000000000..d088a43d438a5 --- /dev/null +++ b/change/@fluentui-web-components-a9829849-1747-4588-aadf-da70207d0cf0.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "Reset web-components for v3 development", + "packageName": "@fluentui/web-components", + "email": "miroslav.stastny@microsoft.com", + "dependentChangeType": "none" +} diff --git a/packages/web-components/.storybook/preview-body.html b/packages/web-components/.storybook/preview-body.html deleted file mode 100644 index 996c666f92e71..0000000000000 --- a/packages/web-components/.storybook/preview-body.html +++ /dev/null @@ -1,12 +0,0 @@ -
- - Direction - RTL - LTR - - - Luminance - Dark - Light - -
diff --git a/packages/web-components/.storybook/preview.js b/packages/web-components/.storybook/preview.js index 95d4b56fba6ff..f240e287648af 100644 --- a/packages/web-components/.storybook/preview.js +++ b/packages/web-components/.storybook/preview.js @@ -1,15 +1,10 @@ import { addons } from '@storybook/addons'; import { DOCS_RENDERED } from '@storybook/core-events'; import * as Fluent from '../src/index-rollup'; -import { fillColor, neutralLayer1, neutralLayer2 } from '../src/design-tokens'; import webcomponentsTheme from './theme'; -import { toggleBgMode, toggleLtr } from '../public/switches'; Fluent; -document.getElementById('luminance-switch').addEventListener('change', toggleBgMode, false); -document.getElementById('direction-switch').addEventListener('change', toggleLtr, false); - export const parameters = { layout: 'fullscreen', controls: { expanded: true }, diff --git a/packages/web-components/docs/api-report.md b/packages/web-components/docs/api-report.md index 8609a999c7d84..89e2eb718dbf1 100644 --- a/packages/web-components/docs/api-report.md +++ b/packages/web-components/docs/api-report.md @@ -4,1730 +4,8 @@ ```ts -import { Accordion } from '@microsoft/fast-foundation'; -import { AccordionItem } from '@microsoft/fast-foundation'; -import { AccordionItemOptions } from '@microsoft/fast-foundation'; -import { Anchor as Anchor_2 } from '@microsoft/fast-foundation'; -import { AnchoredRegion } from '@microsoft/fast-foundation'; -import { Badge as Badge_2 } from '@microsoft/fast-foundation'; -import { BaseProgress } from '@microsoft/fast-foundation'; -import { Behavior } from '@microsoft/fast-element'; -import { Breadcrumb } from '@microsoft/fast-foundation'; -import { BreadcrumbItem } from '@microsoft/fast-foundation'; -import { BreadcrumbItemOptions } from '@microsoft/fast-foundation'; -import { Button as Button_2 } from '@microsoft/fast-foundation'; -import { CalendarOptions } from '@microsoft/fast-foundation'; -import { Card as Card_2 } from '@microsoft/fast-foundation'; -import { CheckboxOptions } from '@microsoft/fast-foundation'; -import { Combobox as Combobox_2 } from '@microsoft/fast-foundation'; -import { ComboboxOptions } from '@microsoft/fast-foundation'; -import { Constructable } from '@microsoft/fast-element'; -import type { Container } from '@microsoft/fast-foundation'; -import { CSSDesignToken } from '@microsoft/fast-foundation'; -import { CSSDirective } from '@microsoft/fast-element'; -import { DataGrid } from '@microsoft/fast-foundation'; -import { DataGridCell } from '@microsoft/fast-foundation'; -import { DataGridRow } from '@microsoft/fast-foundation'; -import { DesignSystem } from '@microsoft/fast-foundation'; -import { DesignToken } from '@microsoft/fast-foundation'; -import { Dialog } from '@microsoft/fast-foundation'; -import { Direction } from '@microsoft/fast-web-utilities'; -import { Divider } from '@microsoft/fast-foundation'; -import { ElementDefinitionContext } from '@microsoft/fast-foundation'; -import { ElementStyles } from '@microsoft/fast-element'; -import { FASTElement } from '@microsoft/fast-element'; -import { Flipper } from '@microsoft/fast-foundation'; -import { FlipperOptions } from '@microsoft/fast-foundation'; -import { FoundationElement } from '@microsoft/fast-foundation'; -import { FoundationElementDefinition } from '@microsoft/fast-foundation'; -import { FoundationElementRegistry } from '@microsoft/fast-foundation'; -import { HorizontalScroll as HorizontalScroll_2 } from '@microsoft/fast-foundation'; -import { HorizontalScrollOptions } from '@microsoft/fast-foundation'; -import { Listbox as Listbox_2 } from '@microsoft/fast-foundation'; -import { ListboxOption } from '@microsoft/fast-foundation'; -import { Menu as Menu_2 } from '@microsoft/fast-foundation'; -import { MenuItem } from '@microsoft/fast-foundation'; -import { MenuItemOptions } from '@microsoft/fast-foundation'; -import { NumberField as NumberField_2 } from '@microsoft/fast-foundation'; -import { NumberFieldOptions } from '@microsoft/fast-foundation'; -import { OverrideFoundationElementDefinition } from '@microsoft/fast-foundation'; -import { ProgressOptions } from '@microsoft/fast-foundation'; -import { ProgressRingOptions } from '@microsoft/fast-foundation'; -import { Radio } from '@microsoft/fast-foundation'; -import { RadioGroup } from '@microsoft/fast-foundation'; -import { RadioOptions } from '@microsoft/fast-foundation'; -import { Search as Search_2 } from '@microsoft/fast-foundation'; -import { SearchOptions } from '@microsoft/fast-foundation'; -import { Select as Select_2 } from '@microsoft/fast-foundation'; -import { SelectOptions } from '@microsoft/fast-foundation'; -import { Skeleton } from '@microsoft/fast-foundation'; -import { Slider } from '@microsoft/fast-foundation'; -import { SliderLabel } from '@microsoft/fast-foundation'; -import { SliderOptions } from '@microsoft/fast-foundation'; -import { Switch } from '@microsoft/fast-foundation'; -import { SwitchOptions } from '@microsoft/fast-foundation'; -import { Tab } from '@microsoft/fast-foundation'; -import { TabPanel } from '@microsoft/fast-foundation'; -import { Tabs } from '@microsoft/fast-foundation'; -import { TextArea as TextArea_2 } from '@microsoft/fast-foundation'; -import { TextField as TextField_2 } from '@microsoft/fast-foundation'; -import { Toolbar as Toolbar_2 } from '@microsoft/fast-foundation'; -import { Tooltip as Tooltip_2 } from '@microsoft/fast-foundation'; -import { TreeItem } from '@microsoft/fast-foundation'; -import { TreeItemOptions } from '@microsoft/fast-foundation'; -import { TreeView } from '@microsoft/fast-foundation'; -import { ViewTemplate } from '@microsoft/fast-element'; - -// @public (undocumented) -export const accentBaseColor: CSSDesignToken; - -// Warning: (ae-internal-missing-underscore) The name "AccentButtonStyles" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal (undocumented) -export const AccentButtonStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition, interactivitySelector: string, nonInteractivitySelector?: string) => ElementStyles; - -// @public (undocumented) -export const accentFillActive: CSSDesignToken; - -// @public (undocumented) -export const accentFillActiveDelta: DesignToken; - -// @public (undocumented) -export const accentFillFocus: CSSDesignToken; - -// @public (undocumented) -export const accentFillFocusDelta: DesignToken; - -// @public (undocumented) -export const accentFillHover: CSSDesignToken; - -// @public (undocumented) -export const accentFillHoverDelta: DesignToken; - -// @public (undocumented) -export const accentFillRecipe: DesignToken; - -// @public (undocumented) -export const accentFillRest: CSSDesignToken; - -// @public (undocumented) -export const accentFillRestDelta: DesignToken; - -// @public (undocumented) -export const accentForegroundActive: CSSDesignToken; - -// @public (undocumented) -export const accentForegroundActiveDelta: DesignToken; - -// @public @deprecated (undocumented) -export const accentForegroundCut: CSSDesignToken; - -// @public @deprecated (undocumented) -export const accentForegroundCutLarge: CSSDesignToken; - -// @public (undocumented) -export const accentForegroundFocus: CSSDesignToken; - -// @public (undocumented) -export const accentForegroundFocusDelta: DesignToken; - -// @public (undocumented) -export const accentForegroundHover: CSSDesignToken; - -// @public (undocumented) -export const accentForegroundHoverDelta: DesignToken; - -// @public (undocumented) -export const accentForegroundRecipe: DesignToken; - -// @public (undocumented) -export const accentForegroundRest: CSSDesignToken; - -// @public (undocumented) -export const accentForegroundRestDelta: DesignToken; - -// @public (undocumented) -export const accentPalette: DesignToken>; - -// @public (undocumented) -export const accentStrokeControlActive: CSSDesignToken; - -// @public (undocumented) -export const accentStrokeControlFocus: CSSDesignToken; - -// @public (undocumented) -export const accentStrokeControlHover: CSSDesignToken; - -// @public (undocumented) -export const accentStrokeControlRecipe: DesignToken; - -// @public (undocumented) -export const accentStrokeControlRest: CSSDesignToken; - -export { Accordion } - -export { AccordionItem } - -// @public -export const accordionItemStyles: (context: ElementDefinitionContext, definition: AccordionItemOptions) => ElementStyles; - -// @public -export const accordionStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// @public -export const allComponents: { - fluentAccordion: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentAccordionItem: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentAnchor: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentAnchoredRegion: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentBadge: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentBreadcrumb: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentBreadcrumbItem: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentButton: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentCalendar: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentCard: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentCheckbox: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentCombobox: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentDataGrid: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentDataGridCell: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentDataGridRow: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentDesignSystemProvider: (overrideDefinition?: OverrideFoundationElementDefinition< { - baseName: string; - template: ViewTemplate; - styles: ElementStyles; - }> | undefined) => FoundationElementRegistry< { - baseName: string; - template: ViewTemplate; - styles: ElementStyles; - }, DesignSystemProvider>; - fluentDialog: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentDivider: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentFlipper: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentHorizontalScroll: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentListbox: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentOption: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentMenu: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentMenuItem: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentNumberField: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentProgress: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentProgressRing: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentRadio: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentRadioGroup: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentSearch: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentSelect: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentSkeleton: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentSlider: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentSliderLabel: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentSwitch: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - fluentTabs: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentTab: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentTabPanel: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentTextArea: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentTextField: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentToolbar: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentTooltip: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentTreeView: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - fluentTreeItem: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - register(container?: Container, ...rest: any[]): void; -}; - -// Warning: (ae-internal-missing-underscore) The name "ambientShadow" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal @deprecated -export const ambientShadow = "0 0 2px rgba(0, 0, 0, 0.14)"; - -// Warning: (ae-internal-missing-underscore) The name "Anchor" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export class Anchor extends Anchor_2 { - // @public - appearance?: AnchorAppearance; - // (undocumented) - appearanceChanged(oldValue: AnchorAppearance, newValue: AnchorAppearance): void; - // (undocumented) - connectedCallback(): void; - defaultSlottedContentChanged(): void; -} - -// @public -export type AnchorAppearance = ButtonAppearance | 'hypertext'; - -export { AnchoredRegion } - -// @public -export const anchoredRegionStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// @public -export const anchorStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// Warning: (ae-internal-missing-underscore) The name "Badge" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export class Badge extends Badge_2 { - // (undocumented) - appearance: BadgeAppearance; -} - -// @public -export type BadgeAppearance = 'accent' | 'lightweight' | 'neutral' | string; - -// @public -export const badgeStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// Warning: (ae-internal-missing-underscore) The name "baseButtonStyles" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export const baseButtonStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition, interactivitySelector: string, nonInteractivitySelector?: string) => ElementStyles; - -// @public (undocumented) -export const baseHeightMultiplier: CSSDesignToken; - -// @public (undocumented) -export const baseHorizontalSpacingMultiplier: CSSDesignToken; - -// Warning: (ae-internal-missing-underscore) The name "baseInputStyles" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export const baseInputStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition, logicalControlSelector: string) => ElementStyles; - -// @public (undocumented) -export const baseLayerLuminance: CSSDesignToken; - -// @public (undocumented) -export const bodyFont: CSSDesignToken; - -export { Breadcrumb } - -export { BreadcrumbItem } - -// @public -export const breadcrumbItemStyles: (context: ElementDefinitionContext, definition: BreadcrumbItemOptions) => ElementStyles; - -// @public -export const breadcrumbStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// Warning: (ae-internal-missing-underscore) The name "Button" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export class Button extends Button_2 { - // @public - appearance: ButtonAppearance; - // (undocumented) - appearanceChanged(oldValue: ButtonAppearance, newValue: ButtonAppearance): void; - // (undocumented) - connectedCallback(): void; - defaultSlottedContentChanged(): void; -} - -// @public -export type ButtonAppearance = 'accent' | 'lightweight' | 'neutral' | 'outline' | 'stealth'; - -// @public -export const buttonStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// @public (undocumented) -export class Card extends Card_2 { - cardFillColor: string; - // (undocumented) - connectedCallback(): void; - // @internal (undocumented) - handleChange(source: any, propertyName: string): void; - neutralPaletteSource: string; -} - -// @public -export const cardStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// @public -export const checkboxStyles: (context: ElementDefinitionContext, definition: CheckboxOptions) => ElementStyles; - -// @public (undocumented) -export interface ColorRecipe { - // (undocumented) - evaluate(element: HTMLElement, reference?: Swatch): Swatch; -} - -// Warning: (ae-internal-missing-underscore) The name "Combobox" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export class Combobox extends Combobox_2 { - // @public - appearance: ComboboxAppearance; - // (undocumented) - appearanceChanged(oldValue: ComboboxAppearance, newValue: ComboboxAppearance): void; - // (undocumented) - connectedCallback(): void; -} - -// @public -export type ComboboxAppearance = 'filled' | 'outline'; - -// @public -export const comboboxStyles: (context: ElementDefinitionContext, definition: ComboboxOptions) => ElementStyles; - -// @public (undocumented) -export const controlCornerRadius: CSSDesignToken; - -// @public @deprecated (undocumented) -export const cornerRadius: CSSDesignToken; - -export { DataGrid } - -export { DataGridCell } - -// @public -export const dataGridCellStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -export { DataGridRow } - -// @public -export const dataGridRowStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// @public -export const dataGridStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// @public (undocumented) -export const density: CSSDesignToken; - -// @public -export class DesignSystemProvider extends FoundationElement { - constructor(); - accentBaseColor: Swatch; - accentFillActiveDelta: number; - accentFillFocusDelta: number; - accentFillHoverDelta: number; - accentFillRestDelta: number; - accentForegroundActiveDelta: number; - accentForegroundFocusDelta: number; - accentForegroundHoverDelta: number; - accentForegroundRestDelta: number; - baseHeightMultiplier: number; - baseHorizontalSpacingMultiplier: number; - baseLayerLuminance: number; - // (undocumented) - connectedCallback(): void; - controlCornerRadius: number; - density: number; - designUnit: number; - direction: Direction; - disabledOpacity: number; - fillColor: Swatch; - focusStrokeWidth: number; - layerCornerRadius: number; - neutralBaseColor: Swatch; - neutralFillActiveDelta: number; - neutralFillFocusDelta: number; - neutralFillHoverDelta: number; - neutralFillInputActiveDelta: number; - neutralFillInputFocusDelta: number; - neutralFillInputHoverDelta: number; - neutralFillInputRestDelta: number; - neutralFillLayerRestDelta: number; - neutralFillRestDelta: number; - neutralFillStealthActiveDelta: number; - neutralFillStealthFocusDelta: number; - neutralFillStealthHoverDelta: number; - neutralFillStealthRestDelta: number; - neutralFillStrongActiveDelta: number; - neutralFillStrongFocusDelta: number; - neutralFillStrongHoverDelta: number; - neutralStrokeActiveDelta: number; - neutralStrokeDividerRestDelta: number; - neutralStrokeFocusDelta: number; - neutralStrokeHoverDelta: number; - neutralStrokeRestDelta: number; - noPaint: boolean; - strokeWidth: number; - typeRampBaseFontSize: string; - typeRampBaseLineHeight: string; - typeRampMinus1FontSize: string; - typeRampMinus1LineHeight: string; - typeRampMinus2FontSize: string; - typeRampMinus2LineHeight: string; - typeRampPlus1FontSize: string; - typeRampPlus1LineHeight: string; - typeRampPlus2FontSize: string; - typeRampPlus2LineHeight: string; - typeRampPlus3FontSize: string; - typeRampPlus3LineHeight: string; - typeRampPlus4FontSize: string; - typeRampPlus4LineHeight: string; - typeRampPlus5FontSize: string; - typeRampPlus5LineHeight: string; - typeRampPlus6FontSize: string; - typeRampPlus6LineHeight: string; -} - -// @public (undocumented) -export const designUnit: CSSDesignToken; - -export { Dialog } - -// @public -export const dialogStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// @public (undocumented) -export const direction: CSSDesignToken; - -// Warning: (ae-internal-missing-underscore) The name "directionalShadow" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal @deprecated (undocumented) -export const directionalShadow = "0 calc(var(--elevation) * 0.5px) calc((var(--elevation) * 1px)) rgba(0, 0, 0, 0.2)"; - -// @public -export class DirectionalStyleSheetBehavior implements Behavior { - constructor(ltr: ElementStyles | null, rtl: ElementStyles | null); - // @internal (undocumented) - bind(source: FASTElement & HTMLElement): void; - // @internal (undocumented) - unbind(source: FASTElement & HTMLElement): void; -} - -// @public (undocumented) -export const disabledOpacity: CSSDesignToken; - -export { Divider } - -// @public -export const dividerStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// @public @deprecated (undocumented) -export const elevatedCornerRadius: CSSDesignToken; - -// @public @deprecated -export const elevation: string; - -// @public (undocumented) -export interface ElevationRecipe { - // (undocumented) - evaluate(element: HTMLElement, size: number, reference?: Swatch): string; -} - -// @public (undocumented) -export const elevationShadowCardActive: CSSDesignToken; - -// @public (undocumented) -export const elevationShadowCardActiveSize: CSSDesignToken; - -// @public (undocumented) -export const elevationShadowCardFocus: CSSDesignToken; - -// @public (undocumented) -export const elevationShadowCardFocusSize: CSSDesignToken; - -// @public (undocumented) -export const elevationShadowCardHover: CSSDesignToken; - -// @public (undocumented) -export const elevationShadowCardHoverSize: CSSDesignToken; - -// @public (undocumented) -export const elevationShadowCardRest: CSSDesignToken; - -// @public (undocumented) -export const elevationShadowCardRestSize: CSSDesignToken; - -// @public (undocumented) -export const elevationShadowDialog: CSSDesignToken; - -// @public (undocumented) -export const elevationShadowDialogSize: CSSDesignToken; - -// @public (undocumented) -export const elevationShadowFlyout: CSSDesignToken; - -// @public (undocumented) -export const elevationShadowFlyoutSize: CSSDesignToken; - -// @public (undocumented) -export const elevationShadowRecipe: DesignToken; - -// @public (undocumented) -export const elevationShadowTooltip: CSSDesignToken; - -// @public (undocumented) -export const elevationShadowTooltipSize: CSSDesignToken; - -// @public (undocumented) -export const fillColor: CSSDesignToken; - -export { Flipper } - -// @public -export const flipperStyles: (context: ElementDefinitionContext, definition: FlipperOptions) => ElementStyles; - -// @public -export const fluentAccordion: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentAccordionItem: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// Warning: (ae-incompatible-release-tags) The symbol "fluentAnchor" is marked as @public, but its signature references "Anchor" which is marked as @internal -// -// @public -export const fluentAnchor: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @beta -export const fluentAnchoredRegion: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// Warning: (ae-incompatible-release-tags) The symbol "fluentBadge" is marked as @public, but its signature references "Badge" which is marked as @internal -// -// @public -export const fluentBadge: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentBreadcrumb: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentBreadcrumbItem: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// Warning: (ae-incompatible-release-tags) The symbol "fluentButton" is marked as @public, but its signature references "Button" which is marked as @internal -// -// @public -export const fluentButton: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentCalendar: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentCard: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentCheckbox: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentCombobox: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentDataGrid: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentDataGridCell: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentDataGridRow: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentDesignSystemProvider: (overrideDefinition?: OverrideFoundationElementDefinition< { -baseName: string; -template: ViewTemplate; -styles: ElementStyles; -}> | undefined) => FoundationElementRegistry< { -baseName: string; -template: ViewTemplate; -styles: ElementStyles; -}, typeof DesignSystemProvider>; - -// @public -export const fluentDialog: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentDivider: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentFlipper: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentHorizontalScroll: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentListbox: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentMenu: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentMenuItem: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentNumberField: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentOption: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentProgress: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentProgressRing: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentRadio: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentRadioGroup: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentSearch: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentSelect: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentSkeleton: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentSlider: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentSliderLabel: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentSwitch: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentTab: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentTabPanel: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentTabs: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// Warning: (ae-incompatible-release-tags) The symbol "fluentTextArea" is marked as @public, but its signature references "TextArea" which is marked as @internal -// -// @public -export const fluentTextArea: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// Warning: (ae-incompatible-release-tags) The symbol "fluentTextField" is marked as @public, but its signature references "TextField" which is marked as @internal -// -// @public -export const fluentTextField: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// Warning: (ae-incompatible-release-tags) The symbol "fluentToolbar" is marked as @public, but its signature references "Toolbar" which is marked as @internal -// -// @public -export const fluentToolbar: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// Warning: (ae-incompatible-release-tags) The symbol "fluentTooltip" is marked as @public, but its signature references "Tooltip" which is marked as @internal -// -// @public -export const fluentTooltip: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public -export const fluentTreeItem: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry>; - -// @public -export const fluentTreeView: (overrideDefinition?: OverrideFoundationElementDefinition | undefined) => FoundationElementRegistry; - -// @public @deprecated (undocumented) -export const focusOutlineWidth: CSSDesignToken; - -// @public (undocumented) -export const focusStrokeInner: CSSDesignToken; - -// @public (undocumented) -export const focusStrokeInnerRecipe: DesignToken; - -// @public (undocumented) -export const focusStrokeOuter: CSSDesignToken; - -// @public (undocumented) -export const focusStrokeOuterRecipe: DesignToken; - -// @public (undocumented) -export const focusStrokeWidth: CSSDesignToken; - -// @public -export const focusTreatmentBase: CSSDirective; - -// @public -export const focusTreatmentTight: CSSDirective; - -// @public (undocumented) -export const fontWeight: CSSDesignToken; - -// @public (undocumented) -export const foregroundOnAccentActive: CSSDesignToken; - -// @public @deprecated (undocumented) -export const foregroundOnAccentActiveLarge: CSSDesignToken; - -// @public (undocumented) -export const foregroundOnAccentFocus: CSSDesignToken; - -// @public @deprecated (undocumented) -export const foregroundOnAccentFocusLarge: CSSDesignToken; - -// @public (undocumented) -export const foregroundOnAccentHover: CSSDesignToken; - -// @public @deprecated (undocumented) -export const foregroundOnAccentHoverLarge: CSSDesignToken; - -// @public @deprecated (undocumented) -export const foregroundOnAccentLargeRecipe: DesignToken; - -// @public (undocumented) -export const foregroundOnAccentRecipe: DesignToken; - -// @public (undocumented) -export const foregroundOnAccentRest: CSSDesignToken; - -// @public @deprecated (undocumented) -export const foregroundOnAccentRestLarge: CSSDesignToken; - -// @public -export const heightNumber: CSSDirective; - -// Warning: (ae-internal-missing-underscore) The name "HorizontalScroll" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal (undocumented) -export class HorizontalScroll extends HorizontalScroll_2 { - // @public (undocumented) - connectedCallback(): void; -} - -// @public -export const horizontalScrollStyles: (context: ElementDefinitionContext, definition: HorizontalScrollOptions) => ElementStyles; - -// Warning: (ae-internal-missing-underscore) The name "HypertextStyles" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal (undocumented) -export const HypertextStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition, interactivitySelector: string, nonInteractivitySelector?: string) => ElementStyles; - -// Warning: (ae-internal-missing-underscore) The name "inputFilledStyles" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export const inputFilledStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition, logicalControlSelector: string, interactivitySelector?: string) => ElementStyles; - -// Warning: (ae-internal-missing-underscore) The name "inputForcedColorStyles" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal (undocumented) -export const inputForcedColorStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition, logicalControlSelector: string, interactivitySelector?: string) => ElementStyles; - -// Warning: (ae-internal-missing-underscore) The name "inputOutlineStyles" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export const inputOutlineStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition, logicalControlSelector: string, interactivitySelector?: string) => ElementStyles; - -// Warning: (ae-internal-missing-underscore) The name "inputStateStyles" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export const inputStateStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition, logicalControlSelector: string) => ElementStyles; - -// @public (undocumented) -export interface InteractiveColorRecipe { - // (undocumented) - evaluate(element: HTMLElement, reference?: Swatch): InteractiveSwatchSet; -} - -// @public (undocumented) -export interface InteractiveSwatchSet { - active: Swatch; - focus: Swatch; - hover: Swatch; - rest: Swatch; -} - -// Warning: (ae-internal-missing-underscore) The name "isDark" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export function isDark(color: Swatch): boolean; - -// @public (undocumented) -export const layerCornerRadius: CSSDesignToken; - -// Warning: (ae-internal-missing-underscore) The name "LightweightButtonStyles" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal (undocumented) -export const LightweightButtonStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition, interactivitySelector: string, nonInteractivitySelector?: string) => ElementStyles; - -// @public (undocumented) -export class Listbox extends Listbox_2 { -} - -// @public -export const listboxStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// @public -export class Menu extends Menu_2 { - // @internal (undocumented) - connectedCallback(): void; -} - -export { MenuItem } - -// @public -export const menuItemStyles: (context: ElementDefinitionContext, definition: MenuItemOptions) => ElementStyles; - -// @public -export const menuStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// @public (undocumented) -export const neutralBaseColor: CSSDesignToken; - -// Warning: (ae-internal-missing-underscore) The name "NeutralButtonStyles" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal (undocumented) -export const NeutralButtonStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition, interactivitySelector: string, nonInteractivitySelector?: string) => ElementStyles; - -// @public @deprecated (undocumented) -export const neutralContrastFillActive: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralContrastFillActiveDelta: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralContrastFillFocus: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralContrastFillFocusDelta: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralContrastFillHover: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralContrastFillHoverDelta: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralContrastFillRest: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralContrastFillRestDelta: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralDivider: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralDividerRestDelta: DesignToken; - -// @public (undocumented) -export const neutralFillActive: CSSDesignToken; - -// @public (undocumented) -export const neutralFillActiveDelta: DesignToken; - -// @public @deprecated (undocumented) -export const neutralFillCard: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralFillCardDelta: DesignToken; - -// @public (undocumented) -export const neutralFillFocus: CSSDesignToken; - -// @public (undocumented) -export const neutralFillFocusDelta: DesignToken; - -// @public (undocumented) -export const neutralFillHover: CSSDesignToken; - -// @public (undocumented) -export const neutralFillHoverDelta: DesignToken; - -// @public (undocumented) -export const neutralFillInputActive: CSSDesignToken; - -// @public (undocumented) -export const neutralFillInputActiveDelta: DesignToken; - -// @public (undocumented) -export const neutralFillInputAltActive: CSSDesignToken; - -// @public (undocumented) -export const neutralFillInputAltActiveDelta: DesignToken; - -// @public (undocumented) -export const neutralFillInputAltFocus: CSSDesignToken; - -// @public (undocumented) -export const neutralFillInputAltFocusDelta: DesignToken; - -// @public (undocumented) -export const neutralFillInputAltHover: CSSDesignToken; - -// @public (undocumented) -export const neutralFillInputAltHoverDelta: DesignToken; - -// @public (undocumented) -export const neutralFillInputAltRecipe: DesignToken; - -// @public (undocumented) -export const neutralFillInputAltRest: CSSDesignToken; - -// @public (undocumented) -export const neutralFillInputAltRestDelta: DesignToken; - -// @public (undocumented) -export const neutralFillInputFocus: CSSDesignToken; - -// @public (undocumented) -export const neutralFillInputFocusDelta: DesignToken; - -// @public (undocumented) -export const neutralFillInputHover: CSSDesignToken; - -// @public (undocumented) -export const neutralFillInputHoverDelta: DesignToken; - -// @public (undocumented) -export const neutralFillInputRecipe: DesignToken; - -// @public (undocumented) -export const neutralFillInputRest: CSSDesignToken; - -// @public (undocumented) -export const neutralFillInputRestDelta: DesignToken; - -// @public @deprecated (undocumented) -export const neutralFillInverseActive: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralFillInverseActiveDelta: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralFillInverseFocus: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralFillInverseFocusDelta: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralFillInverseHover: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralFillInverseHoverDelta: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralFillInverseRecipe: DesignToken; - -// @public @deprecated (undocumented) -export const neutralFillInverseRest: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralFillInverseRestDelta: CSSDesignToken; - -// @public (undocumented) -export const neutralFillLayerActive: CSSDesignToken; - -// @public (undocumented) -export const neutralFillLayerActiveDelta: DesignToken; - -// @public (undocumented) -export const neutralFillLayerAltRecipe: DesignToken; - -// @public (undocumented) -export const neutralFillLayerAltRest: CSSDesignToken; - -// @public (undocumented) -export const neutralFillLayerAltRestDelta: DesignToken; - -// @public (undocumented) -export const neutralFillLayerHover: CSSDesignToken; - -// @public (undocumented) -export const neutralFillLayerHoverDelta: DesignToken; - -// @public (undocumented) -export const neutralFillLayerRecipe: DesignToken; - -// @public (undocumented) -export const neutralFillLayerRest: CSSDesignToken; - -// @public (undocumented) -export const neutralFillLayerRestDelta: DesignToken; - -// @public (undocumented) -export const neutralFillRecipe: DesignToken; - -// @public (undocumented) -export const neutralFillRest: CSSDesignToken; - -// @public (undocumented) -export const neutralFillRestDelta: DesignToken; - -// @public (undocumented) -export const neutralFillSecondaryActive: CSSDesignToken; - -// @public (undocumented) -export const neutralFillSecondaryActiveDelta: DesignToken; - -// @public (undocumented) -export const neutralFillSecondaryFocus: CSSDesignToken; - -// @public (undocumented) -export const neutralFillSecondaryFocusDelta: DesignToken; - -// @public (undocumented) -export const neutralFillSecondaryHover: CSSDesignToken; - -// @public (undocumented) -export const neutralFillSecondaryHoverDelta: DesignToken; - -// @public (undocumented) -export const neutralFillSecondaryRecipe: DesignToken; - -// @public (undocumented) -export const neutralFillSecondaryRest: CSSDesignToken; - -// @public (undocumented) -export const neutralFillSecondaryRestDelta: DesignToken; - -// @public (undocumented) -export const neutralFillStealthActive: CSSDesignToken; - -// @public (undocumented) -export const neutralFillStealthActiveDelta: DesignToken; - -// @public (undocumented) -export const neutralFillStealthFocus: CSSDesignToken; - -// @public (undocumented) -export const neutralFillStealthFocusDelta: DesignToken; - -// @public (undocumented) -export const neutralFillStealthHover: CSSDesignToken; - -// @public (undocumented) -export const neutralFillStealthHoverDelta: DesignToken; - -// @public (undocumented) -export const neutralFillStealthRecipe: DesignToken; - -// @public (undocumented) -export const neutralFillStealthRest: CSSDesignToken; - -// @public (undocumented) -export const neutralFillStealthRestDelta: DesignToken; - -// @public (undocumented) -export const neutralFillStrongActive: CSSDesignToken; - -// @public (undocumented) -export const neutralFillStrongActiveDelta: DesignToken; - -// @public (undocumented) -export const neutralFillStrongFocus: CSSDesignToken; - -// @public (undocumented) -export const neutralFillStrongFocusDelta: DesignToken; - -// @public (undocumented) -export const neutralFillStrongHover: CSSDesignToken; - -// @public (undocumented) -export const neutralFillStrongHoverDelta: DesignToken; - -// @public (undocumented) -export const neutralFillStrongRecipe: DesignToken; - -// @public (undocumented) -export const neutralFillStrongRest: CSSDesignToken; - -// @public (undocumented) -export const neutralFillStrongRestDelta: DesignToken; - -// @public @deprecated (undocumented) -export const neutralFillToggleActive: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralFillToggleActiveDelta: DesignToken; - -// @public @deprecated (undocumented) -export const neutralFillToggleFocus: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralFillToggleFocusDelta: DesignToken; - -// @public @deprecated (undocumented) -export const neutralFillToggleHover: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralFillToggleHoverDelta: DesignToken; - -// @public @deprecated (undocumented) -export const neutralFillToggleRest: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralFillToggleRestDelta: DesignToken; - -// @public @deprecated (undocumented) -export const neutralFocus: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralFocusInnerAccent: CSSDesignToken; - -// @public (undocumented) -export const neutralForegroundActive: CSSDesignToken; - -// @public (undocumented) -export const neutralForegroundFocus: CSSDesignToken; - -// @public (undocumented) -export const neutralForegroundHint: CSSDesignToken; - -// @public (undocumented) -export const neutralForegroundHintRecipe: DesignToken; - -// @public (undocumented) -export const neutralForegroundHover: CSSDesignToken; - -// @public (undocumented) -export const neutralForegroundRecipe: DesignToken; - -// @public (undocumented) -export const neutralForegroundRest: CSSDesignToken; - -// @public (undocumented) -export const neutralLayer1: CSSDesignToken; - -// @public (undocumented) -export const neutralLayer1Recipe: DesignToken; - -// @public (undocumented) -export const neutralLayer2: CSSDesignToken; - -// @public (undocumented) -export const neutralLayer2Recipe: DesignToken; - -// @public (undocumented) -export const neutralLayer3: CSSDesignToken; - -// @public (undocumented) -export const neutralLayer3Recipe: DesignToken; - -// @public (undocumented) -export const neutralLayer4: CSSDesignToken; - -// @public (undocumented) -export const neutralLayer4Recipe: DesignToken; - -// @public (undocumented) -export const neutralLayerCardContainer: CSSDesignToken; - -// @public (undocumented) -export const neutralLayerCardContainerRecipe: DesignToken; - -// @public (undocumented) -export const neutralLayerFloating: CSSDesignToken; - -// @public (undocumented) -export const neutralLayerFloatingRecipe: DesignToken; - -// @public @deprecated (undocumented) -export const neutralLayerL1: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralLayerL2: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralLayerL3: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralLayerL4: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralOutlineActive: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralOutlineFocus: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralOutlineHover: CSSDesignToken; - -// @public @deprecated (undocumented) -export const neutralOutlineRest: CSSDesignToken; - -// @public (undocumented) -export const neutralPalette: DesignToken>; - -// @public (undocumented) -export const neutralStrokeActive: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeActiveDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeControlActive: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeControlActiveDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeControlFocus: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeControlFocusDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeControlHover: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeControlHoverDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeControlRecipe: DesignToken; - -// @public (undocumented) -export const neutralStrokeControlRest: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeControlRestDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeDividerRecipe: DesignToken; - -// @public (undocumented) -export const neutralStrokeDividerRest: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeDividerRestDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeFocus: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeFocusDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeHover: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeHoverDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeInputActive: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeInputFocus: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeInputHover: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeInputRecipe: DesignToken; - -// @public (undocumented) -export const neutralStrokeInputRest: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeLayerActive: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeLayerActiveDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeLayerHover: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeLayerHoverDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeLayerRecipe: DesignToken; - -// @public (undocumented) -export const neutralStrokeLayerRest: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeLayerRestDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeRecipe: DesignToken; - -// @public (undocumented) -export const neutralStrokeRest: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeRestDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeStrongActive: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeStrongActiveDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeStrongFocus: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeStrongFocusDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeStrongHover: CSSDesignToken; - -// @public (undocumented) -export const neutralStrokeStrongHoverDelta: DesignToken; - -// @public (undocumented) -export const neutralStrokeStrongRecipe: DesignToken; - -// @public (undocumented) -export const neutralStrokeStrongRest: CSSDesignToken; - -// Warning: (ae-internal-missing-underscore) The name "NumberField" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export class NumberField extends NumberField_2 { - // @public - appearance: NumberFieldAppearance; - // (undocumented) - connectedCallback(): void; -} - -// @public -export type NumberFieldAppearance = 'filled' | 'outline'; - -// @public -export const numberFieldStyles: (context: ElementDefinitionContext, definition: NumberFieldOptions) => ElementStyles; - -// @public -export const OptionStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// Warning: (ae-internal-missing-underscore) The name "OutlineButtonStyles" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal (undocumented) -export const OutlineButtonStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition, interactivitySelector: string, nonInteractivitySelector?: string) => ElementStyles; - -// @public @deprecated (undocumented) -export const outlineWidth: CSSDesignToken; - -// @public -export interface Palette { - // Warning: (ae-forgotten-export) The symbol "RelativeLuminance" needs to be exported by the entry point index.d.ts - closestIndexOf(reference: RelativeLuminance): number; - colorContrast(reference: Swatch, contrast: number, initialIndex?: number, direction?: 1 | -1): T; - get(index: number): T; - // (undocumented) - readonly source: T; - // (undocumented) - readonly swatches: ReadonlyArray; -} - // @public (undocumented) -export type PaletteRGB = Palette; - -// @public (undocumented) -export const PaletteRGB: Readonly<{ - create: typeof create; - from: typeof from; -}>; - -// @public -export class Progress extends BaseProgress { -} - -// @public -export class ProgressRing extends BaseProgress { -} - -// @public -export const progressRingStyles: (context: ElementDefinitionContext, definition: ProgressRingOptions) => ElementStyles; - -// @public -export const progressStyles: (context: ElementDefinitionContext, definition: ProgressOptions) => ElementStyles; - -// @public -export function provideFluentDesignSystem(element?: HTMLElement): DesignSystem; - -export { Radio } - -export { RadioGroup } - -// @public -export const radioGroupStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// @public -export const RadioStyles: (context: ElementDefinitionContext, definition: RadioOptions) => ElementStyles; - -// @public @deprecated (undocumented) -export interface Recipe { - // (undocumented) - evaluate(element: HTMLElement, reference?: Swatch): T; -} - -// Warning: (ae-internal-missing-underscore) The name "Search" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export class Search extends Search_2 { - // @public - appearance: SearchAppearance; -} - -// @public -export type SearchAppearance = 'filled' | 'outline'; - -// @public -export const searchStyles: (context: ElementDefinitionContext, definition: SearchOptions) => ElementStyles; - -// @public (undocumented) -export const searchTemplate: (context: ElementDefinitionContext, definition: SearchOptions) => ViewTemplate; - -// Warning: (ae-internal-missing-underscore) The name "Select" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export class Select extends Select_2 { - // @public - appearance: SelectAppearance; - // (undocumented) - appearanceChanged(oldValue: SelectAppearance, newValue: SelectAppearance): void; - // (undocumented) - connectedCallback(): void; -} - -// @public -export type SelectAppearance = 'filled' | 'outline' | 'stealth'; - -// @public -export const selectStyles: (context: ElementDefinitionContext, definition: SelectOptions) => ElementStyles; - -export { Skeleton } - -// @public -export const skeletonStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -export { Slider } - -export { SliderLabel } - -// @public -export const sliderLabelStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// @public -export const sliderStyles: (context: ElementDefinitionContext, definition: SliderOptions) => ElementStyles; - -// @public -export enum StandardLuminance { - // (undocumented) - DarkMode = 0.15, - // (undocumented) - LightMode = 0.98 -} - -// Warning: (ae-internal-missing-underscore) The name "StealthButtonStyles" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal (undocumented) -export const StealthButtonStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition, interactivitySelector: string, nonInteractivitySelector?: string) => ElementStyles; - -// @public (undocumented) -export const strokeWidth: CSSDesignToken; - -// @public -export interface Swatch extends RelativeLuminance { - // (undocumented) - contrast(target: RelativeLuminance): number; - // (undocumented) - toColorString(): string; -} - -// @public (undocumented) -export interface SwatchRGB extends Swatch { - // (undocumented) - b: number; - // (undocumented) - g: number; - // (undocumented) - r: number; -} - -// @public (undocumented) -export const SwatchRGB: Readonly<{ - create(r: number, g: number, b: number): SwatchRGB; - from(obj: { - r: number; - g: number; - b: number; - }): SwatchRGB; -}>; - -export { Switch } - -// @public -export const switchStyles: (context: ElementDefinitionContext, definition: SwitchOptions) => ElementStyles; - -export { Tab } - -export { TabPanel } - -// @public -export const tabPanelStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -export { Tabs } - -// @public -export const tabsStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// @public -export const tabStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// Warning: (ae-internal-missing-underscore) The name "TextArea" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export class TextArea extends TextArea_2 { - // @public - appearance: TextAreaAppearance; - // (undocumented) - appearanceChanged(oldValue: TextAreaAppearance, newValue: TextAreaAppearance): void; - // (undocumented) - connectedCallback(): void; -} - -// @public -export type TextAreaAppearance = 'filled' | 'outline'; - -// @public -export const textAreaStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// Warning: (ae-internal-missing-underscore) The name "TextField" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export class TextField extends TextField_2 { - // @public - appearance: TextFieldAppearance; - // (undocumented) - appearanceChanged(oldValue: TextFieldAppearance, newValue: TextFieldAppearance): void; - // (undocumented) - connectedCallback(): void; -} - -// @public -export type TextFieldAppearance = 'filled' | 'outline'; - -// @public -export const textFieldStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// Warning: (ae-internal-missing-underscore) The name "Toolbar" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export class Toolbar extends Toolbar_2 { -} - -// Warning: (ae-internal-missing-underscore) The name "Tooltip" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export class Tooltip extends Tooltip_2 { - // (undocumented) - connectedCallback(): void; -} - -export { TreeItem } - -// @public -export const treeItemStyles: (context: ElementDefinitionContext, definition: TreeItemOptions) => ElementStyles; - -export { TreeView } - -// @public -export const treeViewStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles; - -// @public (undocumented) -export const typeRampBase: CSSDirective; - -// @public (undocumented) -export const typeRampBaseFontSize: CSSDesignToken; - -// @public (undocumented) -export const typeRampBaseFontVariations: CSSDesignToken; - -// @public (undocumented) -export const typeRampBaseLineHeight: CSSDesignToken; - -// @public (undocumented) -export const typeRampMinus1: CSSDirective; - -// @public (undocumented) -export const typeRampMinus1FontSize: CSSDesignToken; - -// @public (undocumented) -export const typeRampMinus1FontVariations: CSSDesignToken; - -// @public (undocumented) -export const typeRampMinus1LineHeight: CSSDesignToken; - -// @public (undocumented) -export const typeRampMinus2: CSSDirective; - -// @public (undocumented) -export const typeRampMinus2FontSize: CSSDesignToken; - -// @public (undocumented) -export const typeRampMinus2FontVariations: CSSDesignToken; - -// @public (undocumented) -export const typeRampMinus2LineHeight: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus1: CSSDirective; - -// @public (undocumented) -export const typeRampPlus1FontSize: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus1FontVariations: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus1LineHeight: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus2: CSSDirective; - -// @public (undocumented) -export const typeRampPlus2FontSize: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus2FontVariations: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus2LineHeight: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus3: CSSDirective; - -// @public (undocumented) -export const typeRampPlus3FontSize: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus3FontVariations: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus3LineHeight: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus4: CSSDirective; - -// @public (undocumented) -export const typeRampPlus4FontSize: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus4FontVariations: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus4LineHeight: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus5: CSSDirective; - -// @public (undocumented) -export const typeRampPlus5FontSize: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus5FontVariations: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus5LineHeight: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus6: CSSDirective; - -// @public (undocumented) -export const typeRampPlus6FontSize: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus6FontVariations: CSSDesignToken; - -// @public (undocumented) -export const typeRampPlus6LineHeight: CSSDesignToken; - -// Warnings were encountered during analysis: -// -// dist/dts/color/palette.d.ts:70:5 - (ae-forgotten-export) The symbol "create" needs to be exported by the entry point index.d.ts -// dist/dts/color/palette.d.ts:71:5 - (ae-forgotten-export) The symbol "from" needs to be exported by the entry point index.d.ts -// dist/dts/custom-elements.d.ts:52:5 - (ae-incompatible-release-tags) The symbol "fluentAnchor" is marked as @public, but its signature references "Anchor" which is marked as @internal -// dist/dts/custom-elements.d.ts:54:5 - (ae-incompatible-release-tags) The symbol "fluentBadge" is marked as @public, but its signature references "Badge" which is marked as @internal -// dist/dts/custom-elements.d.ts:57:5 - (ae-incompatible-release-tags) The symbol "fluentButton" is marked as @public, but its signature references "Button" which is marked as @internal -// dist/dts/custom-elements.d.ts:96:5 - (ae-incompatible-release-tags) The symbol "fluentTextArea" is marked as @public, but its signature references "TextArea" which is marked as @internal -// dist/dts/custom-elements.d.ts:97:5 - (ae-incompatible-release-tags) The symbol "fluentTextField" is marked as @public, but its signature references "TextField" which is marked as @internal -// dist/dts/custom-elements.d.ts:98:5 - (ae-incompatible-release-tags) The symbol "fluentToolbar" is marked as @public, but its signature references "Toolbar" which is marked as @internal -// dist/dts/custom-elements.d.ts:99:5 - (ae-incompatible-release-tags) The symbol "fluentTooltip" is marked as @public, but its signature references "Tooltip" which is marked as @internal +export const empty = ""; // (No @packageDocumentation comment for this package) diff --git a/packages/web-components/public/switches.ts b/packages/web-components/public/switches.ts deleted file mode 100644 index 87e9f8f69db50..0000000000000 --- a/packages/web-components/public/switches.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Direction } from '@microsoft/fast-web-utilities'; -import { baseLayerLuminance, direction, StandardLuminance } from '../src/index'; - -export function toggleBgMode() { - const storyContainer = document.querySelector('.docs-story')!; - const bgChecked = this.checked; - if (bgChecked) { - baseLayerLuminance.setValueFor(storyContainer, StandardLuminance.DarkMode); - } else { - baseLayerLuminance.setValueFor(storyContainer, StandardLuminance.LightMode); - } -} - -export function toggleLtr() { - const storyContainer = document.querySelector('.docs-story')!; - const dirChecked = this.checked; - if (dirChecked) { - storyContainer.style.direction = 'rtl'; - direction.setValueFor(storyContainer, Direction.rtl); - } else { - storyContainer.style.direction = 'ltr'; - direction.setValueFor(storyContainer, Direction.ltr); - } -} diff --git a/packages/web-components/src/__test__/setup-node.ts b/packages/web-components/src/__test__/setup-node.ts deleted file mode 100644 index dcaafc32eab1a..0000000000000 --- a/packages/web-components/src/__test__/setup-node.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* eslint-disable */ -if (window.document && !window.document.createRange) { - window.document.createRange = () => ({ - setStart: () => {}, - setEnd: () => {}, - // @ts-ignore - commonAncestorContainer: { - nodeName: 'BODY', - ownerDocument: document, - }, - }); -} - -if (!window.matchMedia) { - // @ts-ignore - window.matchMedia = - window.matchMedia || - function () { - return { - matches: false, - addListener: function () {}, - removeListener: function () {}, - }; - }; -} diff --git a/packages/web-components/src/_docs/design-system/color-explorer.stories.mdx b/packages/web-components/src/_docs/design-system/color-explorer.stories.mdx deleted file mode 100644 index c6d79c5a193ff..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer.stories.mdx +++ /dev/null @@ -1,16 +0,0 @@ -import { Canvas, Meta, Story } from '@storybook/addon-docs'; -import { App, init } from './color-explorer'; - - - -## Color Explorer - -This tool illustrates how the Adaptive Color system works using recipes to evaluate colors relative to their background context. -All components are styled using these recipes and will adjust accordingly. - -Note that while hex values are provided, they should not be used in code aside from specifying the base colors used to create each palette. -They may be used for legacy frameworks that don't support the color model to match the visuals from the web components. - -export const temp = init(); - - diff --git a/packages/web-components/src/_docs/design-system/color-explorer/app.ts b/packages/web-components/src/_docs/design-system/color-explorer/app.ts deleted file mode 100644 index 14ed65e42ca71..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/app.ts +++ /dev/null @@ -1,286 +0,0 @@ -import { parseColorHexRGB } from '@microsoft/fast-colors'; -import { attr, css, customElement, FASTElement, html, observable, ref, repeat, when } from '@microsoft/fast-element'; -import { DesignToken } from '@microsoft/fast-foundation'; -import { - accentBaseColor, - baseLayerLuminance, - ColorRecipe, - neutralBaseColor, - neutralLayer1Recipe, - neutralLayer2Recipe, - neutralLayer3Recipe, - neutralLayer4Recipe, - neutralLayerCardContainerRecipe, - neutralLayerFloatingRecipe, - PaletteRGB, - StandardLuminance, - Swatch, - SwatchRGB, -} from '../../../index-rollup'; -import { ComponentTypes } from './component-types'; -import { AppColorBlock } from './components/color-block'; -import { AppControlPane } from './components/control-pane'; -import { AppGradient } from './components/gradient'; -import { AppSampleApp } from './components/sample-app'; - -AppColorBlock; -AppControlPane; -AppGradient; -AppSampleApp; - -const sampleTemplate = html` - - - - - - - - -`; - -const colorBlockTemplate = html` - ${repeat( - x => x.backgrounds(), - html` - - `, - )} -`; - -const template = html` -
-
-
-
-
- -
-
- -
-
-
- ${when(x => x.componentType === ComponentTypes.sample, sampleTemplate)} - ${when(x => x.componentType !== ComponentTypes.sample, colorBlockTemplate)} -
-
-
-
-
- - - -
-
-
-`; - -const styles = css` - :host { - } - - .container { - display: flex; - flex-direction: column; - } - - .container.fill { - width: 100%; - height: 1200px; - } - - .row { - position: relative; - display: flex; - flex-direction: row; - flex-basis: auto; - } - - .row.fill { - flex: 1; - overflow: hidden; - } - - .canvas { - min-width: 300px; - flex-grow: 1; - } - - .gradient { - height: 20px; - } - - .control-pane-container { - height: 100%; - z-index: 1; - padding: 40px; - position: relative; - overflow: auto; - width: 310px; - box-sizing: border-box; - } - - app-color-block { - min-width: 400px; - } -`; - -export interface SwatchInfo { - index: number; - color: string; - title?: string; -} - -@customElement({ - name: 'app-main', - template, - styles, -}) -export class App extends FASTElement { - canvasElement: HTMLDivElement; - - @attr({ attribute: 'component-type' }) - componentType: ComponentTypes = ComponentTypes.backplate; - - @attr({ attribute: 'neutral-color' }) - neutralColor: string; - private neutralColorChanged(prev: string | undefined, next: string) { - if (this.canvasElement && next) { - const swatch: Swatch = SwatchRGB.from(parseColorHexRGB(next)!); - neutralBaseColor.setValueFor(this.canvasElement, swatch); - - this.neutralPalette = PaletteRGB.from(swatch as SwatchRGB).swatches.map((x: SwatchRGB) => x.toColorString()); - } - } - - @observable - neutralPalette: string[] = []; - - @attr({ attribute: 'accent-color' }) - accentColor: string; - private accentColorChanged(prev: string | undefined, next: string) { - if (this.canvasElement && next) { - const swatch: Swatch = SwatchRGB.from(parseColorHexRGB(next)!); - accentBaseColor.setValueFor(this.canvasElement, swatch); - - this.accentPalette = PaletteRGB.from(swatch as SwatchRGB).swatches.map((x: SwatchRGB) => x.toColorString()); - } - } - - @observable - accentPalette: string[] = []; - - @observable - showOnlyLayerBackgrounds: boolean = true; - - connectedCallback() { - super.connectedCallback(); - this.neutralColorChanged(undefined, this.neutralColor); - this.accentColorChanged(undefined, this.accentColor); - } - - backgrounds(): Array { - const neutralLayers: Array = this.lightModeLayers.concat(this.darkModeLayers); - - return this.showOnlyLayerBackgrounds - ? neutralLayers - : this.neutralPalette.map((color: string, index: number): SwatchInfo => { - const neutralLayerIndex: number = neutralLayers.findIndex( - (config: SwatchInfo): boolean => config.color === color, - ); - - return { - index, - color, - title: neutralLayerIndex !== -1 ? neutralLayers[neutralLayerIndex].title : undefined, - }; - }); - } - - private layerRecipes: Array<[DesignToken, string]> = [ - [neutralLayerFloatingRecipe, 'neutralLayerFloating'], - [neutralLayerCardContainerRecipe, 'neutralLayerCardContainer'], - [neutralLayer1Recipe, 'neutralLayer1'], - [neutralLayer2Recipe, 'neutralLayer2'], - [neutralLayer3Recipe, 'neutralLayer3'], - [neutralLayer4Recipe, 'neutralLayer4'], - ]; - - private resolveLayerRecipes = (luminance: number): Array => { - const designSystemElement = document.createElement('div'); - this.canvasElement.appendChild(designSystemElement); - baseLayerLuminance.setValueFor(designSystemElement, luminance); - - return this.layerRecipes - .map((conf: [DesignToken, string]): SwatchInfo => { - const color = conf[0].getValueFor(document.body).evaluate(designSystemElement).toColorString(); - return { - index: this.neutralPalette.indexOf(color), - color: color, - title: conf[1], - }; - }) - .reduce((accum: Array, value: SwatchInfo): Array => { - const colorIndex: number = accum.findIndex((config: SwatchInfo): boolean => config.color === value.color); - - return colorIndex === -1 - ? accum.concat(value) - : accum.map( - (config: SwatchInfo, index: number): SwatchInfo => - index === colorIndex - ? { - index: this.neutralPalette.indexOf(value.color), - color: value.color, - title: value.title!.concat(', ', config.title!), - } - : config, - ); - }, []) - .sort((a: SwatchInfo, b: SwatchInfo): number => a.index - b.index); - }; - - private get lightModeLayers(): Array { - return this.resolveLayerRecipes(StandardLuminance.LightMode); - } - - private get darkModeLayers(): Array { - return this.resolveLayerRecipes(StandardLuminance.DarkMode); - } - - controlPaneHandler(e: CustomEvent) { - const detail: { field: string; value: any } = e.detail; - this[detail.field] = detail.value; - } -} diff --git a/packages/web-components/src/_docs/design-system/color-explorer/colors.ts b/packages/web-components/src/_docs/design-system/color-explorer/colors.ts deleted file mode 100644 index c036ef77003cc..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/colors.ts +++ /dev/null @@ -1,25 +0,0 @@ -export enum AccentColors { - black = '#000000', - white = '#FFFFFF', - magenta = '#DA1A5F', - blue = '#0078D4', - green = '#107C10', - purple = '#5C2D91', - orange = '#D83B01', - yellow = '#F2C812', -} - -export const neutralColors: string[] = [ - '#808080', - '#73818C', - '#718E71', - '#7F738C', - '#8C7A73', - '#0078D4', - '#107C10', - '#5C2D91', - '#D83B01', -]; - -export const defaultAccentColor: string = AccentColors.blue; -export const defaultNeutralColor: string = neutralColors[0]; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/component-types.ts b/packages/web-components/src/_docs/design-system/color-explorer/component-types.ts deleted file mode 100644 index 8031c10ad6bd2..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/component-types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export enum ComponentTypes { - backplate = 'backplate', - text = 'text', - form = 'form', - sample = 'sample', -} diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/color-block.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/color-block.ts deleted file mode 100644 index a8bde30f0028d..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/color-block.ts +++ /dev/null @@ -1,438 +0,0 @@ -import { parseColorHexRGB } from '@microsoft/fast-colors'; -import { attr, css, customElement, DOM, FASTElement, html, when } from '@microsoft/fast-element'; -import { display } from '@microsoft/fast-foundation'; -import { - accentFillActive, - accentFillHover, - accentFillRest, - accentForegroundActive, - accentForegroundHover, - accentForegroundRest, - fillColor, - focusStrokeInner, - focusStrokeOuter, - foregroundOnAccentRest, - neutralFillActive, - neutralFillHover, - neutralFillInputRest, - neutralFillRest, - neutralFillStealthActive, - neutralFillStealthHover, - neutralFillStealthRest, - neutralFillStrongActive, - neutralFillStrongHover, - neutralFillStrongRest, - neutralForegroundHint, - neutralForegroundRest, - neutralStrokeActive, - neutralStrokeDividerRest, - neutralStrokeHover, - neutralStrokeRest, - SwatchRGB, -} from '../../../../index-rollup'; -import { ComponentTypes } from '../component-types'; -import { AppSwatch } from './swatch'; - -AppSwatch; - -const backplateComponents = html` - -`; - -const textComponents = html` - -`; - -const formComponents = html` - -`; - -const template = html` -

- SWATCH ${x => x.index} - ${x => x.color.toUpperCase()} - ${when( - x => x.layerName, - html` -

- ${x => x.layerName} -

- `, - )} -

- -
- ${when(x => x.component === ComponentTypes.backplate, backplateComponents)} - ${when(x => x.component === ComponentTypes.text, textComponents)} - ${when(x => x.component === ComponentTypes.form, formComponents)} -
-`; - -const styles = css` - ${display('flex')} - - :host { - flex-direction: column; - flex-grow: 1; - align-items: stretch; - text-align: center; - position: relative; - transition: opacity 0.1s linear; - height: 100%; - min-height: 100%; - background-color: ${fillColor}; - color: ${neutralForegroundRest}; - } - - .title { - margin: 16px auto 4px; - font-weight: 600; - height: 34px; - color: ${neutralForegroundHint}; - } - - .title code { - font-weight: normal; - } - - .content { - flex-grow: 1; - display: flex; - flex-direction: column; - align-items: center; - padding: 0 48px 36px; - } - - .example { - height: 60px; - display: flex; - align-items: center; - margin-top: 24px; - } - - .hint_text { - color: ${neutralForegroundHint}; - } - - .divider { - width: 150px; - } -`; - -@customElement({ - name: 'app-color-block', - template, - styles, -}) -export class AppColorBlock extends FASTElement { - @attr index: number; - - @attr component: ComponentTypes; - - @attr color: string; - private colorChanged(): void { - DOM.queueUpdate(() => this.updateColor()); - } - - @attr({ attribute: 'layer-name' }) layerName?: string; - - private updateColor(): void { - if (this.color && this.$fastController.isConnected) { - const color = parseColorHexRGB(this.color)!; - fillColor.setValueFor(this, SwatchRGB.from(color)); - } - } -} diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/README.md b/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/README.md deleted file mode 100644 index 3cfead7d9db4a..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Color Picker - -This component has been forked from `@microsoft/fast-tooling` as the addition of the tooling dependency creates a circular dependency which was found while attempting to update shared dependencies. This folder can be safely removed once we are able to update the color picker's accessibility to a point where it can be added to the `@microsoft/fast-components` package. At that point in time, both the color explorer and `@microsoft/fast-tooling` would take a dependency on the core component. diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.form-associated.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.form-associated.ts deleted file mode 100644 index 5e210c6bf1085..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.form-associated.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { FormAssociated, FoundationElement } from '@microsoft/fast-foundation'; - -/* eslint-disable */ -class _ColorPicker extends FoundationElement {} -interface _ColorPicker extends FormAssociated {} -/* eslint-enable */ - -/** - * A form-associated base class for the component. - * - * @internal - */ -export class FormAssociatedColorPicker extends FormAssociated(_ColorPicker) { - proxy: HTMLInputElement = document.createElement('input'); -} diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.styles.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.styles.ts deleted file mode 100644 index 92b26b68ec1e9..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.styles.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { css, ElementStyles } from "@microsoft/fast-element"; -import { - ElementDefinitionContext, - FoundationElementDefinition, -} from "@microsoft/fast-foundation"; - -export const colorPickerStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition -) => ElementStyles = () => css` - .popup, - .popup__open { - display: none; - padding: 2px; - flex-direction: row; - background-color: var(--neutral-layer-floating); - border: calc(var(--outline-width) * 1px) solid var(--neutral-outline-rest); - border-radius: calc(var(--corner-radius) * 1px); - } - .popup__open { - display: flex; - position: absolute; - z-index: 1; - margin-left: -32px; - } - .pickers { - margin: 4px 6px 4px 4px; - } - .inputs { - width: 65px; - margin: 0 4px 4px 0; - } - .pickers-saturation { - position: relative; - width: 200px; - height: 200px; - margin-bottom: 17px; - background: linear-gradient(to top, #000 0%, rgba(0, 0, 0, 0) 100%), - linear-gradient(to right, #fff 0%, rgba(255, 255, 255, 0) 100%); - background-color: #f00; - border: 1px solid #fff; - } - .saturation-indicator { - position: absolute; - top: 0; - left: 0; - border: 1px solid #fff; - border-radius: 3px; - width: 4px; - height: 4px; - pointer-events: none; - } - .pickers-hue { - position: relative; - width: 200px; - height: 30px; - margin-bottom: 17px; - border: 1px solid #fff; - background: linear-gradient( - to right, - #f00 0%, - #ff0 16.66%, - #0f0 33.33%, - #0ff 50%, - #00f 66.66%, - #f0f 83.33%, - #f00 100% - ); - } - .hue-indicator, - .alpha-indicator { - position: absolute; - left: 0; - top: -2px; - border: 1px solid #fff; - width: 1px; - height: 32px; - pointer-events: none; - margin-left: 1px; - } - .pickers-alpha { - position: relative; - width: 200px; - height: 30px; - border: 1px solid #fff; - background-image: linear-gradient(45deg, #999 25%, transparent 25%), - linear-gradient(-45deg, #999 25%, transparent 25%), - linear-gradient(45deg, transparent 75%, #999 75%), - linear-gradient(-45deg, transparent 75%, #999 75%); - background-size: 20px 20px; - background-position: 0 0, 0 10px, 10px -10px, -10px 0px; - background-color: #fff; - } - .alpha-mask { - width: 100%; - height: 100%; - background-image: linear-gradient(to right, transparent, #f00); - margin-bottom: 5px; - } - .control-color { - position: relative; - display: inline-block; - width: 25px; - height: 25px; - margin-top: auto; - margin-bottom: auto; - border: 1px solid var(--fast-tooling-l1-color, #333333); - } - .control-color::before { - position: absolute; - content: ""; - left: 0; - right: 0; - top: 0; - bottom: 0; - background-image: linear-gradient( - to bottom left, - transparent calc(50% - 1px), - var(--fast-tooling-l1-color, #333333), - transparent calc(50% + 1px) - ); - } - .control-color::after { - position: absolute; - content: ""; - left: 0; - right: 0; - top: 0; - bottom: 0; - background-color: var(--selected-color-value); - } -`; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.template.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.template.ts deleted file mode 100644 index 44016477a72f8..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.template.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { html, ref, ViewTemplate } from '@microsoft/fast-element'; -import { ElementDefinitionContext, TextField } from '@microsoft/fast-foundation'; -import { ColorPicker } from './color-picker'; - -/** - * The template for the color picker component. - * @public - */ -export const colorPickerTemplate: (context: ElementDefinitionContext) => ViewTemplate = context => { - return html` - - `; -}; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.ts deleted file mode 100644 index f33a01bb0a26e..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/color-picker.ts +++ /dev/null @@ -1,377 +0,0 @@ -import { ColorHSV, ColorRGBA64, hsvToRGB, parseColor, rgbToHSV } from '@microsoft/fast-colors'; -import { attr, DOM, observable } from '@microsoft/fast-element'; -import { isNullOrWhiteSpace } from '@microsoft/fast-web-utilities'; -import { FormAssociatedColorPicker } from './color-picker.form-associated'; - -/** - * This is currently experimental, any use of the color picker must include the following - * imports and register with the DesignSystem - * - * import { fastTextField } from "@microsoft/fast-components"; - * import { DesignSystem } from "@microsoft/fast-foundation"; - * DesignSystem.getOrCreate().register(fastTextField()); - */ - -/** - * Simple class for storing all of the color picker UI observable values. - */ -class ColorPickerUI { - public RGBColor: ColorRGBA64; - public HSVColor: ColorHSV; - public HueCSSColor: string; - public HuePosition: number; - public SatValTopPos: number; - public SatValLeftPos: number; - public AlphaPos: number; - - constructor(rgbColor: ColorRGBA64, hsvColor: ColorHSV) { - this.RGBColor = rgbColor; - this.HSVColor = hsvColor; - this.HueCSSColor = hsvToRGB(new ColorHSV(this.HSVColor.h, 1, 1)).toStringHexRGB(); - this.HuePosition = (this.HSVColor.h / 360) * 100; - this.SatValLeftPos = this.HSVColor.s * 100; - this.SatValTopPos = 100 - this.HSVColor.v * 100; - this.AlphaPos = this.RGBColor.a * 100; - } -} - -/** - * A Color Picker Custom HTML Element. - * - * @public - */ -export class ColorPicker extends FormAssociatedColorPicker { - /** - * When true, the control will be immutable by user interaction. See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly | readonly HTML attribute} for more information. - * @public - * @remarks - * HTML Attribute: readonly - */ - @attr({ attribute: 'readonly', mode: 'boolean' }) - public readOnly: boolean; - private readOnlyChanged(): void { - if (this.proxy instanceof HTMLElement) { - this.proxy.readOnly = this.readOnly; - } - } - - /** - * Indicates that this element should get focus after the page finishes loading. See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefautofocus | autofocus HTML attribute} for more information. - * @public - * @remarks - * HTML Attribute: autofocus - */ - @attr({ mode: 'boolean' }) - public autofocus: boolean; - private autofocusChanged(): void { - if (this.proxy instanceof HTMLElement) { - this.proxy.autofocus = this.autofocus; - } - } - - /** - * Sets the placeholder value of the element, generally used to provide a hint to the user. - * @public - * @remarks - * HTML Attribute: placeholder - * Using this attribute does is not a valid substitute for a labeling element. - */ - @attr - public placeholder: string; - private placeholderChanged(): void { - if (this.proxy instanceof HTMLElement) { - this.proxy.placeholder = this.placeholder; - } - } - - /** - * Flag indicating that the color UI is visible. - */ - @observable - public open: boolean; - - /** - * Flag indicating that the color UI is activily listening for mouse move and up events. - */ - @observable - public mouseActive: boolean = false; - - /** - * Object containing all of the properties displayed in the color picker UI. - */ - @observable - public uiValues: ColorPickerUI = new ColorPickerUI(new ColorRGBA64(1, 0, 0), new ColorHSV(0, 1, 1)); - - /** - * A reference to the internal input element - * @internal - */ - public control: HTMLInputElement; - - /** - * A reference to the HTMLElement that is the current target of mouse move events. - */ - private currentMouseTarget: HTMLElement | null = null; - - /** - * A string indicating which of the three graphical elements is the current mouse target. ['sv','h','a'] - */ - private currentMouseParam: string | null; - - /** - * The ColorRGBA64 representation of the current color value. - */ - private currentRGBColor: ColorRGBA64; - - /** - * The ColorHSV representation of the current color value. - */ - private currentHSVColor: ColorHSV; - - /** - * @internal - */ - public connectedCallback(): void { - super.connectedCallback(); - this.open = false; - this.initColorValues(); - this.proxy.setAttribute('type', 'color'); - - if (this.autofocus) { - DOM.queueUpdate(() => { - this.focus(); - }); - } - } - - /** - * Handles the focus event. When the template has focus the color UI will be visable. - * @internal - */ - public handleFocus(): void { - // Re-init colors in case the value changed externally since the UI was last visible. - this.initColorValues(); - this.open = true; - } - - /** - * Handles the blur event. Hides the color UI when the template loses focus. - * @internal - */ - public handleBlur(): void { - this.open = false; - } - - /** - * Handles the internal control's `input` event. This event is fired whenever a user types directly into the primary text field. - * @internal - */ - public handleTextInput(): void { - this.initialValue = this.control.value; - if (this.isValideCSSColor(this.value)) { - this.currentRGBColor = parseColor(this.value)!; - this.currentHSVColor = rgbToHSV(this.currentRGBColor); - this.updateUIValues(false); - this.$emit('change'); - } - } - - /** - * Handles the mouse down event on the Sat/Val square and Hue and Alpha sliders. Sets the current targeted element and begins listening for mouse move events. - * @param param ['sv','h','a'] - string specifying which color property is being modified with the mouse. - * @param e - A reference to the mouse event. - */ - public handleMouseDown(param: string, e: MouseEvent) { - this.currentMouseTarget = e.composedPath()[0] as HTMLElement; - this.currentMouseParam = param; - this.updateFromMouseEvent(e.pageX, e.pageY); - this.mouseActive = true; - } - - /** - * Handles the mouse move event within the color UI. Is only called once the mouseActive is set to true. - * @param e - Reference to the Mouse Event - */ - public handleMouseMove(e: MouseEvent) { - this.updateFromMouseEvent(e.pageX, e.pageY); - } - - /** - * Handles the mouse up event within the color UI. Disables listening for mouse move events. - * @param e - Reference to the Mouse Event - */ - public handleMouseUp(e: MouseEvent) { - this.updateFromMouseEvent(e.pageX, e.pageY); - this.currentMouseTarget = null; - this.currentMouseParam = null; - this.mouseActive = false; - } - - /** - * Handles changes to any of the color property text inputs typed by the user. - * @param param ['r','g','b','a','h','s','v'] - String specifying which color value is being modified. - * @param e - Reference to the event. - */ - public handleTextValueInput(param: string, e: Event) { - const inputVal = (e.composedPath()[0] as HTMLInputElement).value; - if (isNullOrWhiteSpace(inputVal) || Number.isNaN(inputVal)) { - return; - } - const newVal: number = parseInt(inputVal, 10); - - if (['r', 'g', 'b', 'a'].includes(param)) { - if ((param !== 'a' && this.isValidRGB(newVal)) || (param === 'a' && this.isValidAlpha(newVal))) { - this.currentRGBColor = new ColorRGBA64( - param === 'r' ? newVal / 255 : this.currentRGBColor.r, - param === 'g' ? newVal / 255 : this.currentRGBColor.g, - param === 'b' ? newVal / 255 : this.currentRGBColor.b, - param === 'a' ? newVal / 100 : this.currentRGBColor.a, - ); - this.currentHSVColor = rgbToHSV(this.currentRGBColor); - this.updateUIValues(true); - } - } else if (['h', 's', 'v'].includes(param)) { - if ((param !== 'h' && this.isValidSaturationValue(newVal)) || (param === 'h' && this.isValidHue(newVal))) { - this.updateHSV( - param === 'h' ? newVal : this.currentHSVColor.h, - param === 's' ? newVal / 100 : this.currentHSVColor.s, - param === 'v' ? newVal / 100 : this.currentHSVColor.v, - ); - } - } - } - - /** - * Change event handler for inner control. - * @remarks - * "Change" events are not `composable` so they will not - * permeate the shadow DOM boundary. This fn effectively proxies - * the change event, emitting a `change` event whenever the internal - * control emits a `change` event - * @internal - */ - public handleChange(): void { - this.$emit('change'); - } - - /** - * Initialize internal color values based on input value and set the UI elements - * to the correct positions / values. - */ - private initColorValues(): void { - if (!isNullOrWhiteSpace(this.value)) { - this.currentRGBColor = parseColor(this.value)!; - } else { - this.currentRGBColor = new ColorRGBA64(1, 0, 0, 1); - } - this.currentHSVColor = rgbToHSV(this.currentRGBColor); - this.updateUIValues(false); - } - - /** - * Determines if a number value is within the valid range for an R, G, or B color channel. - * @param val - Number to be evaluated. - */ - private isValidRGB(val: number): boolean { - return val >= 0 && val <= 255; - } - - /** - * Determines if a number value is within the valid range for the alpha channel. - * @param val - Number to be evaluated. - */ - private isValidAlpha(val: number): boolean { - return val >= 0 && val <= 100; - } - - /** - * Determines if a number value is within the valid range for the saturation or value color channels. - * @param val - Number to be evaluated. - */ - private isValidSaturationValue(val: number): boolean { - return val >= 0 && val <= 100; - } - - /** - * Determines if a number value is within the valid range for the hue color channel. - * @param val - Number to be evaluated. - */ - private isValidHue(val: number): boolean { - return val >= 0 && val <= 359; - } - - /** - * Checks if input is a valid CSS color. - * After placing an invalid css color value into a color style property the value will be an empty string when read back. - * @internal - */ - private isValideCSSColor(testValue: string): boolean { - /* Set the background color of the proxy element since it is not visible in the UI. */ - this.proxy.style.backgroundColor = ''; - this.proxy.style.backgroundColor = testValue; - /* Read the value back out. If it was not a valid color value then it will be an empty string when read back out. */ - return this.proxy.style.backgroundColor !== ''; - } - - /** - * Update the current color values to a new HSV color. - * @param hue The new Hue value. - * @param sat The new saturation value. - * @param val The new Value value. - */ - private updateHSV(hue: number, sat: number, val: number) { - this.currentHSVColor = new ColorHSV(hue, sat, val); - this.currentRGBColor = hsvToRGB(this.currentHSVColor, this.currentRGBColor.a); - this.updateUIValues(true); - } - - /** - * Update the current color values based on the mouse position over one of the three UI elements (hue, saturation/value, or alpha). - * @param pageX The pageX position of the mouse. - * @param pageY The pageY position of the mouse. - */ - private updateFromMouseEvent(pageX: number, pageY: number) { - const pos: DOMRect = this.currentMouseTarget!.getBoundingClientRect(); - let x = pageX - pos.left; - let y = pageY - pos.top; - const width = pos.width; - const height = pos.height; - - if (x > width) x = width; - if (y > height) y = height; - if (x < 0) x = 0; - if (y < 0) y = 0; - - if (this.currentMouseParam === 'h') { - this.updateHSV((359 * x) / width, this.currentHSVColor.s, this.currentHSVColor.v); - } else if (this.currentMouseParam === 'sv') { - this.updateHSV( - this.currentHSVColor.h, - Math.round((x * 100) / width) / 100, - Math.round(100 - (y * 100) / height) / 100, - ); - } else if (this.currentMouseParam === 'a') { - this.currentRGBColor = new ColorRGBA64( - this.currentRGBColor.r, - this.currentRGBColor.g, - this.currentRGBColor.b, - Math.round((x * 100) / width) / 100, - ); - this.updateUIValues(true); - } - } - - /** - * Update the UI values with the current color. This updates the position of the indicators over the Sat/Val, Hue and Alpha elements - * and the values in all of the text fields at once. - * @param updateValue - Flag to trigger updating of the main text field value and emitting the change event. - */ - private updateUIValues(updateValue: boolean) { - this.uiValues = new ColorPickerUI(this.currentRGBColor, this.currentHSVColor); - if (updateValue) { - this.initialValue = - this.currentRGBColor.a !== 1 ? this.currentRGBColor.toStringWebRGBA() : this.currentRGBColor.toStringHexRGB(); - this.$emit('change'); - } - } -} diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/index.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/index.ts deleted file mode 100644 index 28ff96fdb617b..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/color-picker/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { ColorPicker } from './color-picker'; -import { colorPickerTemplate as template } from './color-picker.template'; -import { colorPickerStyles as styles } from './color-picker.styles'; - -/** - * A web component used for updating color values. - * - * @alpha - * @remarks - * HTML Element: \ - */ -export const fastToolingColorPicker = ColorPicker.compose({ - baseName: 'color-picker', - template, - styles, -}); diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/control-pane.styles.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/control-pane.styles.ts deleted file mode 100644 index 510c419ff87c9..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/control-pane.styles.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { css } from "@microsoft/fast-element"; -import { display } from "@microsoft/fast-foundation"; -import { typeRampPlus1FontSize, typeRampPlus1LineHeight } from "../../../../../index-rollup"; - -export const controlPaneStyles = css` - ${display("flex")} :host { - flex: 0 1 auto; - flex-direction: column; - gap: 24px; - } - - .title { - font-size: ${typeRampPlus1FontSize}; - line-height: ${typeRampPlus1LineHeight}; - } - - fluent-radio-group::part(positioning-region) { - gap: 8px; - } -`; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/control-pane.template.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/control-pane.template.ts deleted file mode 100644 index 0416a2360379a..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/control-pane.template.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { html, repeat } from '@microsoft/fast-element'; -import { Checkbox, RadioGroup } from '@microsoft/fast-foundation'; -import { ComponentTypes } from '../../component-types'; -import { ColorPicker } from '../color-picker/color-picker'; -import { ControlPane } from './control-pane'; - -function titleCase(str: string): string { - return str.split('').reduce((accumulated: string, value: string, index: number): string => { - return accumulated.concat(index === 0 ? value.toUpperCase() : value); - }, ''); -} - -export const controlPaneTemplate = html` - -`; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/control-pane.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/control-pane.ts deleted file mode 100644 index 0a7f2d67ee096..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/control-pane.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { observable } from '@microsoft/fast-element'; -import { FoundationElement } from '@microsoft/fast-foundation'; - -export class ControlPane extends FoundationElement { - @observable - componentType: string; - - @observable - accentColor: string; - - @observable - neutralColor: string; - - @observable - showOnlyLayerBackgrounds: boolean = true; - - updateFormValue(field: string, value: any) { - this.$emit('formvaluechange', { field: field, value: value }); - } -} diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/index.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/index.ts deleted file mode 100644 index 627cd75d17470..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/control-pane/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { customElement } from '@microsoft/fast-element'; -import { ControlPane } from './control-pane'; -import { controlPaneTemplate as template } from './control-pane.template'; -import { controlPaneStyles as styles } from './control-pane.styles'; - -@customElement({ - name: 'app-control-pane', - template, - styles, -}) -export class AppControlPane extends ControlPane {} -export * from './control-pane.template'; -export * from './control-pane.styles'; -export * from './control-pane'; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/gradient/gradient.styles.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/gradient/gradient.styles.ts deleted file mode 100644 index fa5ef1854872c..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/gradient/gradient.styles.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { css } from "@microsoft/fast-element"; -import { display } from "@microsoft/fast-foundation"; - -export const gradientStyles = css` - ${display("flex")} :host { - display: flex; - width: 100%; - } - - a { - display: flex; - flex: 1; - height: 100%; - } - - a.marked { - position: relative; - } - - a.marked::before { - width: 6px; - height: 6px; - margin: 0 auto; - content: ""; - opacity: 0.7; - position: relative; - border: solid 1px currentcolor; - border-radius: 50%; - display: block; - align-self: center; - } -`; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/gradient/gradient.template.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/gradient/gradient.template.ts deleted file mode 100644 index 4217f7cd6a719..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/gradient/gradient.template.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { parseColor } from '@microsoft/fast-colors'; -import { html, repeat } from '@microsoft/fast-element'; -import { isDark, SwatchRGB } from '../../../../../index-rollup'; -import { Gradient } from './gradient'; - -function getColor(background) { - const bg = parseColor(background)!; - const darkMode = isDark(SwatchRGB.from(bg)); - return darkMode ? 'white' : 'black'; -} - -export const gradientTemplate = html` - -`; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/gradient/gradient.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/gradient/gradient.ts deleted file mode 100644 index 615604a0acb63..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/gradient/gradient.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { observable } from '@microsoft/fast-element'; -import { FoundationElement } from '@microsoft/fast-foundation'; - -export class Gradient extends FoundationElement { - @observable - colors: string[]; - - @observable - markedColor: string; -} diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/gradient/index.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/gradient/index.ts deleted file mode 100644 index 333ba9afcafd9..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/gradient/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { customElement } from '@microsoft/fast-element'; -import { Gradient } from './gradient'; -import { gradientTemplate as template } from './gradient.template'; -import { gradientStyles as styles } from './gradient.styles'; - -@customElement({ - name: 'app-gradient', - template, - styles, -}) -export class AppGradient extends Gradient {} -export * from './gradient.template'; -export * from './gradient.styles'; -export * from './gradient'; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/layer-background/index.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/layer-background/index.ts deleted file mode 100644 index 99a9999698e4f..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/layer-background/index.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { attr, css, html, nullableNumberConverter } from '@microsoft/fast-element'; -import { DesignToken, DesignTokenChangeRecord, display, FoundationElement } from '@microsoft/fast-foundation'; -import { - baseLayerLuminance, - fillColor, - neutralForegroundRest, - neutralLayer1, - neutralLayer2, - neutralLayer3, - neutralLayer4, - neutralPalette, - Swatch, -} from '../../../../../index-rollup'; - -export class LayerBackground extends FoundationElement { - @attr({ attribute: 'base-layer-luminance', converter: nullableNumberConverter }) - public baseLayerLuminance: number; - private baseLayerLuminanceChanged(prev: number, next: number): void { - baseLayerLuminance.setValueFor(this, this.baseLayerLuminance); - this.updateBackgroundColor(); - } - - @attr({ attribute: 'background-layer-recipe' }) - public backgroundLayerRecipe: string = 'L1'; - private backgroundLayerRecipeChanged(prev: string, next: string): void { - this.updateBackgroundColor(); - } - - private updateBackgroundColor(): void { - if (!this.$fastController.isConnected) { - return; - } - - if (this.backgroundLayerRecipe !== undefined) { - let swatch: Swatch | null = null; - switch (this.backgroundLayerRecipe) { - case 'L1': - swatch = neutralLayer1.getValueFor(this); - break; - case 'L2': - swatch = neutralLayer2.getValueFor(this); - break; - case 'L3': - swatch = neutralLayer3.getValueFor(this); - break; - case 'L4': - swatch = neutralLayer4.getValueFor(this); - break; - } - - if (swatch !== null) { - fillColor.setValueFor(this, swatch); - } - } - } - - public handleChange(record: DesignTokenChangeRecord>): void { - if (record.token === neutralPalette) { - this.updateBackgroundColor(); - } - } - - public connectedCallback(): void { - super.connectedCallback(); - - neutralPalette.subscribe(this); - - this.updateBackgroundColor(); - } -} - -export const layerBackgroundTemplate = html` `; - -export const layerBackgroundStyles = css` - ${display('block')} :host { - background: ${fillColor}; - color: ${neutralForegroundRest}; - } -`; - -export const layerBackground = LayerBackground.compose({ - baseName: 'layer-background', - template: layerBackgroundTemplate, - styles: layerBackgroundStyles, -}); diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/index.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/index.ts deleted file mode 100644 index 7a147d32d98cd..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { customElement } from '@microsoft/fast-element'; -import { SampleApp } from './sample-app'; -import { sampleAppTemplate as template } from './sample-app.template'; -import { sampleAppStyles as styles } from './sample-app.styles'; - -@customElement({ - name: 'app-sample-app', - template, - styles, -}) -export class AppSampleApp extends SampleApp {} -export * from './sample-app.template'; -export * from './sample-app.styles'; -export * from './sample-app'; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/sample-app.styles.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/sample-app.styles.ts deleted file mode 100644 index cdb56cc4d213e..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/sample-app.styles.ts +++ /dev/null @@ -1,182 +0,0 @@ -import { css } from "@microsoft/fast-element"; -import { display, forcedColorsStylesheetBehavior } from "@microsoft/fast-foundation"; -import { SystemColors } from "@microsoft/fast-web-utilities"; -import { - bodyFont, - controlCornerRadius, - designUnit, - elevation, - fillColor, - neutralForegroundHint, - neutralForegroundRest, - typeRampMinus2FontSize, - typeRampPlus3FontSize, - typeRampPlus3LineHeight, -} from "../../../../../index-rollup"; - -export const sampleAppStyles = css` - ${display("flex")} - - :host { - flex-direction: column; - font-family: ${bodyFont}; - color: ${neutralForegroundRest}; - box-sizing: border-box; - min-height: 650px; - min-width: 775px; - background: ${fillColor}; - border-radius: calc(${controlCornerRadius} * 1px); - --elevation: 20; - ${elevation} - --gutter: 20; - } - - app-layer-background { - display: flex; - flex-grow: 1; - } - - p { - margin: 0; - } - - .icon { - pointer-events: none; - } - - .wrapper { - display: flex; - flex-direction: column; - width: 100%; - position: relative; - } - - .toolbar { - display: flex; - align-items: center; - box-sizing: border-box; - height: 40px; - padding: 0 12px; - } - - fast-tabs { - flex-grow: 1; - } - - fast-tabs::part(tablist) { - padding: 0 4px; - align-self: start; - } - - fast-tabs::part(activeIndicator) { - margin: 0; - } - - fast-tab { - padding: calc(${designUnit} * 5px) calc(${designUnit} * 3px); - } - - fast-tab-panel { - padding: 0; - height: 100%; - } - - .content { - display: flex; - align-items: stretch; - width: 100%; - text-align: start; - box-shadow: none; - } - - .pane { - width: 240px; - } - - .pane > fast-listbox { - width: 100%; - } - - .details { - height: unset; - box-shadow: none; - } - - /* wrapper, toolbar, content, pane, details */ - - .content .heading { - font-size: ${typeRampPlus3FontSize}; - line-height: ${typeRampPlus3LineHeight}; - margin: 0; - margin-bottom: 10px; - font-weight: bold; - } - - .icon { - fill: currentColor; - } - - .saturation-slider-track { - height: 100%; - border-radius: calc(${controlCornerRadius} * 1px); - } - - .hue-slider-track { - height: 100%; - border-radius: calc(${controlCornerRadius} * 1px); - background-image: - linear-gradient( - to right, - rgb(255, 0, 0), - rgb(255, 77, 0), - rgb(255, 153, 0), - rgb(255, 230, 0), - rgb(204, 255, 0), - rgb(128, 255, 0), - rgb(51, 255, 0), - rgb(0, 255, 26), - rgb(0, 255, 102), - rgb(0, 255, 179), - rgb(0, 255, 255), - rgb(0, 179, 255), - rgb(0, 102, 255), - rgb(0, 26, 255), - rgb(51, 0, 255), - rgb(128, 0, 255), - rgb(204, 0, 255), - rgb(255, 0, 230), - rgb(255, 0, 153), - rgb(255, 0, 76), - rgb(255, 0, 4) - );" - } - - .responsive-expand-flipper { - position: absolute; - left: -30px; - align-self: center; - display: none; - visibility: hidden; - } - - site-color-swatch { - margin: 0; - } - - fast-slider-label { - font-size: ${typeRampMinus2FontSize}; - color: ${neutralForegroundHint}; - } -`.withBehaviors( - forcedColorsStylesheetBehavior( - css` - .text-container { - color: ${SystemColors.ButtonText}; - } - fast-tab:hover[aria-selected="true"] { - background: ${SystemColors.Highlight}; - fill: ${SystemColors.HighlightText}; - } - ` - ) -); diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/sample-app.template.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/sample-app.template.ts deleted file mode 100644 index cb8ac70c57d5c..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/sample-app.template.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { html } from '@microsoft/fast-element'; -import { AppSamplePage } from '../sample-page'; -// import DataAreaIcon from "@fluentui/svg-icons/icons/data_area_24_regular.svg"; -// import DataHistogramIcon from "@fluentui/svg-icons/icons/data_histogram_24_regular.svg"; -// import DataScatterIcon from "@fluentui/svg-icons/icons/data_scatter_24_regular.svg"; - -AppSamplePage; - -export const sampleAppTemplate = html` - -`; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/sample-app.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/sample-app.ts deleted file mode 100644 index 4eda9c2d561a7..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-app/sample-app.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { FoundationElement } from '@microsoft/fast-foundation'; - -export class SampleApp extends FoundationElement {} diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/index.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/index.ts deleted file mode 100644 index 95280c31e958d..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { customElement } from '@microsoft/fast-element'; -import { SamplePage } from './sample-page'; -import { samplePageStyles as styles } from './sample-page.styles'; -import { samplePageTemplate as template } from './sample-page.template'; - -@customElement({ - name: 'app-sample-page', - template, - styles, -}) -export class AppSamplePage extends SamplePage {} -export * from './sample-page.template'; -export * from './sample-page.styles'; -export * from './sample-page'; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/sample-page.styles.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/sample-page.styles.ts deleted file mode 100644 index 1096822885a17..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/sample-page.styles.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { css } from '@microsoft/fast-element'; -import { display } from '@microsoft/fast-foundation'; -import { accentFillRest, controlCornerRadius, designUnit, neutralForegroundRest } from '../../../../../index-rollup'; - -export const samplePageStyles = css` - ${display('flex')} :host { - display: grid; - grid-gap: calc(var(--gutter) * 2px); - grid-template-columns: auto 300px; - padding: calc(var(--gutter) * 2px); - position: relative; - border-radius: 0 calc(${controlCornerRadius} * 1px) calc(${controlCornerRadius} * 1px) 0; - } - - .image-container { - /** Temp background */ - background: #d6d6d6; - width: 100%; - height: 215px; - display: flex; - } - - .badge { - align-self: flex-end; - margin: calc(var(--gutter) * 1px); - } - - .text-container { - display: flex; - flex-direction: column; - padding: calc(var(--gutter) * 1px); - text-align: start; - color: ${neutralForegroundRest}; - } - - .sample-control { - display: flex; - align-items: center; - width: 100%; - } - - .sample-control-actions { - margin-inline-start: auto; - } - - .sample-control-text { - margin-inline-start: calc(${designUnit} * 2px + 2px); - } - - .sample-control-icon { - width: 21px; - height: 21px; - background-color: ${accentFillRest}; - border-radius: calc(${controlCornerRadius} * 1px); - } - - .preview-controls { - display: grid; - grid-auto-rows: max-content; - grid-gap: 20px; - } - - .control-container { - display: grid; - grid-template-columns: 1fr 1fr; - grid-gap: 20px; - } - - .control-container-2 { - display: grid; - grid-template-columns: 1fr auto auto; - grid-gap: 20px; - } - - .control-container p { - margin-inline-start: calc(${designUnit} * 2px + 2px); - } - - .control-container-grid { - display: grid; - grid-template-columns: auto 1fr; - text-align: start; - color: ${neutralForegroundRest}; - } - - .checkbox { - grid-row: 2; - } - - .checkbox-label { - grid-row: 2; - grid-column: 2; - } - - fast-card { - width: 280px; - } - - fast-badge { - --badge-fill-primary: #e4bc11; - --badge-color-primary: #000000; - } - - fast-slider { - min-width: unset; - } - - fast-tab-panel { - height: 100%; - } - - fast-tab[aria-selected='true'] { - background: transparent; - } - - fast-radio-group.example-radios { - margin: 0; - } - - fast-radio-group.example-radios::part(positioning-region) { - display: grid; - grid-template-columns: auto; - height: 100%; - } - - fast-radio-group.swatches::part(positioning-region) { - display: grid; - grid-gap: 10px; - grid-auto-flow: column; - } -`; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/sample-page.template.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/sample-page.template.ts deleted file mode 100644 index 1489defd2ebcc..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/sample-page.template.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { html } from '@microsoft/fast-element'; -// import MoreIcon from "@fluentui/svg-icons/icons/more_horizontal_20_regular.svg"; -// import DownloadIcon from "@fluentui/svg-icons/icons/arrow_download_20_regular.svg"; -// import PlayIcon from "@fluentui/svg-icons/icons/play_20_regular.svg"; - -export const samplePageTemplate = html` - -`; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/sample-page.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/sample-page.ts deleted file mode 100644 index d0d626527b6cf..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/sample-page/sample-page.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { FoundationElement } from '@microsoft/fast-foundation'; - -export class SamplePage extends FoundationElement {} diff --git a/packages/web-components/src/_docs/design-system/color-explorer/components/swatch.ts b/packages/web-components/src/_docs/design-system/color-explorer/components/swatch.ts deleted file mode 100644 index 9d2cc6f895fd5..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/components/swatch.ts +++ /dev/null @@ -1,182 +0,0 @@ -import { contrastRatio, parseColor } from '@microsoft/fast-colors'; -import { attr, css, customElement, html, observable } from '@microsoft/fast-element'; -import { DesignToken, FoundationElement } from '@microsoft/fast-foundation'; -import { elevation, fillColor, neutralForegroundHint, Swatch } from '../../../../index-rollup'; - -export enum SwatchTypes { - fill = 'fill', - foreground = 'foreground', - outline = 'outline', -} - -const template = html` - -`; - -const styles = css` - :host { - display: grid; - grid-template-columns: auto 1fr auto; - grid-template-rows: auto; - align-items: center; - width: 100%; - padding: 4px 0; - box-sizing: border-box; - color: ${neutralForegroundHint}; - font-size: 12px; - grid-column-gap: 16px; - justify-items: start; - } - :host(.foreground) .icon { - border: 1px solid black; - } - :host(.foreground) .icon::before { - font-size: 13px; - content: 'A'; - font-weight: 400; - } - .icon { - display: flex; - align-items: center; - justify-content: center; - width: 20px; - height: 20px; - border-radius: 2px; - box-sizing: border-box; - --elevation: 4; - ${elevation} - } - .recipe-name { - grid-column: 2; - grid-row: 1; - } - .hex-code { - grid-column: 3; - grid-row: 1; - } -`; - -@customElement({ - name: 'app-swatch', - template, - styles, -}) -export class AppSwatch extends FoundationElement { - @attr - public type: SwatchTypes; - - @attr({ attribute: 'recipe-name' }) - public recipeName: string; - - @observable - public foregroundRecipe?: DesignToken; - public foregroundRecipeChanged() { - this.updateObservables(); - } - - @observable - public fillRecipe?: DesignToken; - public fillRecipeChanged() { - this.updateObservables(); - } - - @observable - public outlineRecipe?: DesignToken; - public outlineRecipeChanged() { - this.updateObservables(); - } - - @observable - public iconStyle: string; - - @observable - public contrastMessage: string; - - @observable - public colorValue: string; - - public connectedCallback() { - super.connectedCallback(); - - const fillColorChangeHandler = () => { - this.updateObservables(); - }; - - fillColor.subscribe( - { - handleChange: fillColorChangeHandler, - }, - this, - ); - - this.updateObservables(); - } - - private updateObservables() { - this.updateIconStyle(); - this.updateContrastMessage(); - this.updateColorValue(); - } - - private tokenCSS(token?: DesignToken): string { - return token && typeof (token as any).createCSS === 'function' ? (token as any).createCSS() : ''; - } - - private evaluateToken(token?: DesignToken): string { - return token?.getValueFor(this).toColorString() || ''; - } - - private updateIconStyle(): void { - const background = `background-color: ${this.tokenCSS(this.fillRecipe)}`; - this.iconStyle = - this.type === SwatchTypes.outline - ? `border: 4px solid ${this.tokenCSS(this.outlineRecipe)}; ${background}` - : this.type === SwatchTypes.foreground - ? `color: ${this.tokenCSS(this.foregroundRecipe)}; ${background}` - : background; - } - - private formatContrast(a?: DesignToken, b?: DesignToken): string { - return a && b - ? contrastRatio(parseColor(this.evaluateToken(a))!, parseColor(this.evaluateToken(b))!).toFixed(2) - : ''; - } - - private formatBackgroundContrast(a?: DesignToken, b?: DesignToken): string { - return `BG contrast: ${this.formatContrast(a, b)} : 1`; - } - - private formatForegroundContrast(a?: DesignToken, b?: DesignToken): string { - return `Text contrast: ${this.formatContrast(a, b)} : 1`; - } - - private updateContrastMessage(): void { - const backgroundContrastMessage: string = this.formatBackgroundContrast( - this.type === SwatchTypes.foreground - ? this.foregroundRecipe - : this.type === SwatchTypes.outline - ? this.outlineRecipe - : this.fillRecipe, - this.type === SwatchTypes.foreground || this.type === SwatchTypes.outline ? this.fillRecipe : fillColor, - ); - - this.contrastMessage = - this.type === SwatchTypes.fill - ? backgroundContrastMessage.concat('\n', this.formatForegroundContrast(this.fillRecipe, this.foregroundRecipe)) - : backgroundContrastMessage; - } - - private updateColorValue(): void { - const recipe = - this.type === SwatchTypes.outline - ? this.outlineRecipe - : this.type === SwatchTypes.foreground - ? this.foregroundRecipe - : this.fillRecipe; - this.colorValue = this.evaluateToken(recipe).toUpperCase(); - } -} diff --git a/packages/web-components/src/_docs/design-system/color-explorer/custom-elements.ts b/packages/web-components/src/_docs/design-system/color-explorer/custom-elements.ts deleted file mode 100644 index fbdfde13091b7..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/custom-elements.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { layerBackground } from './components/layer-background'; - -export { layerBackground }; - -export const appComponents = [layerBackground()]; diff --git a/packages/web-components/src/_docs/design-system/color-explorer/index.ts b/packages/web-components/src/_docs/design-system/color-explorer/index.ts deleted file mode 100644 index 13c40eca0bbe5..0000000000000 --- a/packages/web-components/src/_docs/design-system/color-explorer/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { allComponents as fluentComponents, provideFluentDesignSystem } from '../../../index-rollup'; -import { fastToolingColorPicker } from './components/color-picker'; -import { App } from './app'; -import { appComponents } from './custom-elements'; - -export function init() { - provideFluentDesignSystem() - .register(fluentComponents) - .withPrefix('fast-tooling') - .register(fastToolingColorPicker()) - .withPrefix('app') - .register(appComponents); -} - -App; - -export { App } from './app'; diff --git a/packages/web-components/src/_docs/design-system/design-tokens.stories.mdx b/packages/web-components/src/_docs/design-system/design-tokens.stories.mdx deleted file mode 100644 index f5dd1efb2103f..0000000000000 --- a/packages/web-components/src/_docs/design-system/design-tokens.stories.mdx +++ /dev/null @@ -1,216 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -The FAST Design Token implementation for Fluent uI Web Components is designed to provide first-class support for Design Tokens and make setting, getting, and using Design Tokens simple. - -## What is a Design Token - -A Design Token is a semantic, named variable used to describe a Design System. They often describe design concepts like typography, color, sizes, UI spacing, etc. FAST encourages checking out [the Design Tokens Community Group](https://github.com/design-tokens/community-group#design-tokens) for more information on Design Tokens themselves. - -## FAST Frame Design Tokens - -The `@microsoft/fast-components` have extensive support for predefined design tokens. See [configuring styles](/docs/design-systems/fast-frame#configuring-styles) for details on adjusting or using the existing tokens, or read on to create your own. - -## Create a Token - -> **Note**: -> -> This example uses color because it's an easy concept to describe, but we generally discourage the use of fixed colors as they don't benefit from the [adaptive color system](/docs/design-systems/fast-frame#adaptive-color-system) with support for light and dark mode and other adjustments. - -The first step to using a token is to create it: - -```ts -import { DesignToken } from '@microsoft/fast-foundation'; - -export const specialColor = DesignToken.create('special-color'); -``` - -The type assertion informs what types the token can be set to (and what type will be retrieved), and the name parameter will serve as the CSS Custom Property name (more on that later). - -## Setting Values - -A `DesignToken` _value_ is set for a `FASTElement` or `HTMLBodyElement` node. This allows tokens to be set to different values for distinct DOM trees: - -```ts -const ancestor = document.querySelector('my-element') as FASTElement; -const descendent = ancestor.querySelector('my-element') as FASTElement; - -specialColor.setValueFor(ancestor, '#FFFFFF'); -specialColor.setValueFor(descendent, '#F7F7F7'); -``` - -## Setting a Default Value - -A default value can be set for a token, so that the default value is returned from `getValueFor()` in cases where no other token value is found for a node tree. - -```ts -specialColor.withDefault('#FFFFFF'); -``` - -## Getting Values - -Once the value is set for a node, the value is available to use for that node or any descendent node. The value returned will be the value set for the nearest ancestor (or the element itself). - -```ts -specialColor.getValueFor(ancestor); // "#FFFFFF" -specialColor.getValueFor(descendent); // "#F7F7F7" -``` - -## Deleting Values - -Values can be deleted for a node. Doing so causes retrieval of the nearest ancestor's value instead: - -```ts -specialColor.deleteValueFor(descendent); -specialColor.getValueFor(descendent); // "#FFFFFF" -``` - -## CSS Custom Property emission - -Unless configured not to, a DesignToken emits a token to CSS automatically whenever the value is set for an element. In the case when a DesignToken is assigned a [derived value](#derived-design-token-values), the CSS custom property will also be emitted when any dependent tokens change. - -A DesignToken can be configured **not** to emit to a CSS custom property by passing a configuration with `cssCustomPropertyName` set to `null` during creation: - -```ts -DesignToken.create({ - name: 'my-token', - cssCustomPropertyName: null, -}); -``` - -A DesignToken can also be configured to emit to a CSS custom property that is different than the provided name by providing a CSS custom property name to the configuration: - -```ts -DesignToken.create({ - name: 'my-token', - cssCustomPropertyName: 'my-css-custom-property-name', // Emits to --my-css-custom-property-name -}); -``` - -### Values with a 'createCSS' method - -It is sometimes useful to be able to set a token to a complex object but still use that value in CSS. If a DesignToken is assigned a value with a `createCSS` method on it, the product of that method will be used when emitting to a CSS custom property instead of the Design Token value itself: - -```ts -interface RGBColor { - r: number; - g: number; - b: number; - createCSS(): string; -} - -const extraSpecialColor = DesignToken.create('extra-special-color'); - -const value = { - r: 255, - g: 0, - b: 0, - createCSS() { - return `rgb(${this.r}, ${this.g}, ${this.b})`; - }, -}; - -extraSpecialColor.setValueFor(descendent, value); -``` - -## Subscription - -`DesignToken` supports subscription, notifying a subscriber when a value changes. Subscriptions can subscribe to _any_ change throughout the document tree or they can subscribe changes for specific elements. - -**Example: Subscribe to changes for any element** - -```ts -const subscriber = { - handleChange(record) { - console.log(`DesignToken ${record.token} changed for element ${record.target}`); - }, -}; - -specialColor.subscribe(subscriber); -``` - -**Example: Subscribe to changes a specific element** - -```ts -// ... -const target = document.body.querySelector('#my-element'); - -specialColor.subscribe(subscriber, target); -``` - -Subscribers can be unsubscribed using the `unsubscribe()` method: - -```ts -// ... -specialColor.unsubscribe(subscriber); -specialColor.unsubscribe(subscriber, target); -``` - -## Using Design Tokens in CSS - -Any token can be used directly in a FAST stylesheet by using the Design Token as a CSS directive. Assuming the token value has been set for the element or some ancestor element, the value of the token embedded in the stylesheet will be the token value for that element instance. - -```ts -import { css } from '@microsoft/fast-element'; - -const styles = css` - :host { - background: ${specialColor}; - } -`; -``` - -At runtime, the directive is replaced with a CSS custom property, and the Directive ensures that the CSS custom property is added for the element. - -## Derived Design Token Values - -In the examples above, the design token is always being set to a simple string value. But, we can also set a Design Token to be a function that _derives_ a value. A derived value receives the target element as its only argument and must return a value with a type matching the Design Token: - -```ts -const token = DesignToken.create('token'); -token.setValueFor(target, element => 12); -``` - -The above example is contrived, but the target element can be used to retrieve _other_ Design Tokens: - -**Example: A derived token value that uses another design token** - -```ts -const foregroundColor = DesignToken.create('foreground-color'); - -foregroundColor.setValueFor(target, element => - specialColor.getValueFor(element) === '#FFFFFF' ? '#2B2B2B' : '#262626', -); -``` - -For derived Design Token values, any change to dependent tokens will force the derived value to update (and update the CSS custom property if applicable). The same is true if an observable property is used by the derived value: - -```ts -import { observable } from '@microsoft/fast-element'; - -class ThemeManager { - @observable - theme: 'blue' | 'red' = 'blue'; -} - -const themeManager = new ThemeManager(); - -specialColor.setValueFor(target, () => (themeManager.theme === 'blue' ? '#0000FF' : '#FF0000')); - -themeManager.theme = 'red'; // Forces the derived tokens to re-evaluate and CSS custom properties to update if applicable -``` - -## Aliasing Design Tokens - -In some design systems, Design Tokens may have complex hierarchies with tokens referencing other tokens. This can be accomplished by setting a Design Token to another Design Token. - -```ts -const specialColor = DesignToken.create('special-color'); -const buttonSpecialColor = DesignToken.create('button-special-color'); - -specialColor.setValueFor(target, '#EDEDED'); -buttonSpecialColor.setValueFor(target, specialColor); - -buttonSpecialColor.getValueFor(target); // "#EDEDED" -``` diff --git a/packages/web-components/src/_docs/design-system/high-contrast.stories.mdx b/packages/web-components/src/_docs/design-system/high-contrast.stories.mdx deleted file mode 100644 index 8bbcfd229b027..0000000000000 --- a/packages/web-components/src/_docs/design-system/high-contrast.stories.mdx +++ /dev/null @@ -1,185 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -## Styling components using forced-colors - -High contrast mode uses the CSS media feature, [`forced-colors`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/forced-colors). When `forced-colors` is set to `active`, the user agent will apply a limited color palette to the component. - -**Example:** - -```css -@media (forced-colors: active) { - :host { - background: ButtonFace; - } -} -``` - -FAST has a [forcedColorsStylesheetBehavior](https://github.com/microsoft/fast/blob/master/packages/web-components/fast-foundation/src/utilities/match-media-stylesheet-behavior.ts) utility function that is used to construct `forced-colors` in a stylesheet. This function is passed to the `withBehavior` function from the `css` tagged template object. - -> **Note**: -> -> The reason for this behavior is to avoid the runtime cost of applying `forced-color` style rules when the UA does not match the `forced-colors` @media query. FAST exposes a behavior that conditionally adds and removes stylesheets based on this media query, so forced-colors' stylesheets can then be conditionally applied where necessary. - -**Example** - -```ts -export const ComponentStyles = css` - /* ... */ -`.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host { - background: ButtonFace; - } - `, - ), -); -``` - -## System Color Keyword - -In `forced-colors` mode, the colors on the component are reduced to a limited color palette chosen by the user. The [System Color keywords](https://developer.mozilla.org/en-US/docs/web/css/color_value#System_Colors) defined by the CSS Color Module Level 4 specification expose these user-chosen colors. - -FAST provides a [`SystemColors`](https://github.com/microsoft/fast/blob/master/packages/utilities/fast-web-utilities/src/system-colors.ts) enum to use when setting the color value keywords in a `forced-colors` stylesheet. - -**Example** - -```ts -export const ComponentStyles = css` - /* ... */ -`.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host { - background: ${SystemColors.ButtonFace}; - } - `, - ), -); -``` - -## Forced colors and Windows High Contrast themes - -`forced-colors` works with Windows high contrast mode in Windows, located in Ease of Access within Settings. There are two default themes to test high contrast, `High Contrast Black` and `High Contrast White`. - -![High contrast black theme](https://static.fast.design/assets/high-contrast/hc-black.png) -![High contrast white theme](https://static.fast.design/assets/high-contrast/hc-white.png) - -Here is a 1:1 map between the `forced-colors` keywords and Windows high contrast resource names. - -| forced-colors | Windows | -| --------------------------- | --------------- | -| `CanvasText` | `Text` | -| `LinkText` | `Hyperlinks` | -| `GrayText` | `Disabled Text` | -| `HighlightText` `Highlight` | `Selected Text` | -| `ButtonText` `ButtonFace` | `Button Text` | -| `Canvas` | `Background` | - -## Quick demo - -Here is a simple example of adding high contrast to style an accent button. It has selectors for rest, active, hover, focus, and disabled. - -![Accent button](https://static.fast.design/assets/high-contrast/accent.png) - -```ts -export const AccentButtonStyles = css` - :host([appearance='accent']) { - background: ${accentFillRest}; - color: ${foregroundOnAccentRest}; - } - :host([appearance='accent']:hover) { - background: ${accentFillHover}; - } - :host([appearance='accent']:active) .control:active { - background: ${accentFillActive}; - } - :host([appearance="accent"]) .control:${focusVisible} { - box-shadow: 0 0 0 calc(${focusStrokeWidth} * 1px) inset ${focusStrokeInner}; - } - :host([appearance='accent'][disabled]) { - opacity: ${disabledOpacity}; - background: ${accentFillRest}; - } -`; -``` - -When high contrast is enabled, the system will try to apply the correct color. In the case of this accent button, the system is missing a few things. We do not have a background, `rest` and `hover` states are the same, `focus` is not following the button's `focus` design, and the `disabled` state is too dim. - -![Accent button no forced colors](https://static.fast.design/assets/high-contrast/accent-no-forced-colors.png) - -To fix this, we will pass a [forcedColorsStylesheetBehavior](https://github.com/microsoft/fast/blob/master/packages/web-components/fast-foundation/src/utilities/match-media-stylesheet-behavior.ts) object to `withBehaviors`, using similar selectors, and setting property values with the `SystemColors` keyword. - -```ts -export const AccentButtonStyles = css` - /* ... */ -`.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host([appearance='accent']) .control { - forced-color-adjust: none; - background: ${SystemColors.Highlight}; - color: ${SystemColors.HighlightText}; - } - :host([appearance='accent']) .control:hover, - :host([appearance='accent']:active) .control:active { - background: ${SystemColors.HighlightText}; - border-color: ${SystemColors.Highlight}; - color: ${SystemColors.Highlight}; - } - :host([appearance="accent"]) .control:${focusVisible} { - border-color: ${SystemColors.ButtonText}; - box-shadow: 0 0 0 2px ${SystemColors.HighlightText} inset; - } - :host([appearance='accent'][disabled]), - :host([appearance='accent'][disabled]) .control, - :host([appearance='accent'][disabled]) .control:hover { - background: ${SystemColors.ButtonFace}; - border-color: ${SystemColors.GrayText}; - color: ${SystemColors.GrayText}; - opacity: 1; - } - `, - ), -); -``` - -After adding `forced-colors` and applying `SystemColors` keywords, the accent button now uses `Highlight` as a background for its `rest` state. On the `hover` and `active` states, the background and color from the `rest` state are swapped. A double border treatment is applied when in the `focus` state, and the `disabled` has opacity set to 1 and uses the disabled color, `GrayText`, for color on the border and content. - -![Accent button forced colors](https://static.fast.design/assets/high-contrast/accent-with-forced-colors.png) - -> **Note**: -> -> [forced-color-adjust](https://www.w3.org/TR/css-color-adjust-1/#forced), controls whether the UA system theme color override, should be applied to an element and its descendants. -> The example is set to `none`, because we are overriding to remove the backplate on the text content in the control, that the UA sets on text elements. - -### Further resources - -**Color contrast comparison chart** - -To help determine whether a pair of high contrast colors will meet a color luminosity contrast ratio of at least 10:1, this table uses the high contrast theme color resource names you see in Windows Ease of Access. - -How to read this table: - -- YES - indicates that it is safe to assume this pair of colors will meet high contrast requirements, even in - custom themes. -- `YES*` - indicates that this specific pair of colors meets the high contrast requirements in both High Contrast Black and High Contrast White themes. -- NO - indicates that you should never use this pair of colors as they do not meet high contrast requirements in High Contrast Black and High Contrast White themes. - -| | Text | Hyperlink | Disabled Text | Selected Text (Foreground) | Selected Text (Background) | Button Text (Foreground) | Button Text (Background) | Background | -| ------------------------------ | ---------------- | ---------------- | ---------------- | -------------------------- | -------------------------- | ------------------------ | ------------------------ | ---------------- | -| **Text** | NO | NO | NO | NO | NO | NO | YES | YES | -| **Hyperlink** | NO | NO | NO | `YES*` | NO | NO | `YES*` | YES | -| **Disabled Text** | NO | NO | NO | `YES*` | NO | NO | YES | YES | -| **Selected Text (Foreground)** | NO | `YES*` | `YES* ` | NO | YES | `YES*` | NO | NO | -| **Selected Text (Background)** | NO | NO | NO | YES | NO | NO | `YES*` | `YES*` | -| **Button Text (Foreground)** | NO | NO | NO | `YES*` | NO | NO | YES | YES | -| **Button Text (Background)** | YES | `YES*` | YES | NO | `YES*` | YES | NO | NO | -| **Background** | YES | YES | YES | NO | `YES*` | YES | NO | NO | - -### Microsoft Edge blog - -Microsoft Edge blog has excellent and in-depth information on styling for Windows high contrast using forced-colors. -[Styling for Windows high contrast with new standards for forced colors](https://blogs.windows.com/msedgedev/2020/09/17/styling-for-windows-high-contrast-with-new-standards-for-forced-colors/) diff --git a/packages/web-components/src/_docs/getting-started/customization.stories.mdx b/packages/web-components/src/_docs/getting-started/customization.stories.mdx deleted file mode 100644 index 36d24bc2a6595..0000000000000 --- a/packages/web-components/src/_docs/getting-started/customization.stories.mdx +++ /dev/null @@ -1,238 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -## Styling the components - -The Fluent UI Web Components are designed to be stylistically flexible, allowing dramatic changes to visual design with minimal code changes. This is possible through the extensive use of [Design Tokens](?path=/docs/design-system-design-tokens--page) and an [adaptive color system](#adaptive-color-system). - -### Fluent UI Web Components Design Tokens - -The following Design Tokens can be used to configure components stylistically. - -#### Light and dark mode - -The most common need for setting a token is to switch between light and dark mode. - -- `baseLayerLuminance`: Set to `StandardLuminance.DarkMode` to switch into dark mode. - -This is a decimal value, and the `LightMode` and `DarkMode` constants represent the standard points for light and dark mode. You could set it to any value `0` (black) to `1` (white) depending on your needs. - -#### Layers and fill color - -The second most common need for manually applying color is to define layers. When you adjust `baseLayerLuminance` as above, you're actually adjusting the `neutralLayer*` recipe colors. - -- `fillColor`: Sets a value that _may_ be applied to an element's styles and used as context for child color recipes. The default value is `neutralLayer1`.
- _Ex: Set to `neutralLayer2` for a 'lower' container, like beneath a Card or Accordion._ - -**Important:** This token is easy to misuse and we're evaluating a more elegant solution for this common use case: - -```html -
- - Hello - - ... -
-``` - -```js -const layer = document.getElementById('myCardContainer'); -fillColor.setValueFor(layer, neutralLayer2); -``` - -```css -#myCardContainer { - background-color: ${fillColor}; -} -``` - -The details: Avoid setting this to a fixed color value. The scenario above works because the neutral layer recipe colors _come from_ the neutral palette. The `fillColor` token is used by most color recipes only as a _reference_ for the _luminance_ (or brightness) context. That's because the recipes are still drawing from their palette, and setting the `fillColor` does not _change_ the palette. - -#### Adjust neutral or accent colors - -- `neutralBaseColor`: Set to a custom swatch to use for color recipes for layers and other neutral components.
- _Ex: `SwatchRGB.from(parseColorHexRGB('#A90000')!)`_ -- `accentBaseColor`: Set to a custom swatch to use for color recipes for accent buttons, checkboxes, etc. - -#### Typography - -- `bodyFont`: Used to specify the font string to apply to components. Note that this does not import fonts, so they must either be web standard, assumed to be installed, or imported at the top of your app. - -These tokens and values represent the default Fluent type ramp. The tokens should be used and adjusted relatively. For instance, if the type should be larger overall, increase the size of the entire type ramp instead of restyling a component to use "Plus 1" instead of "base". - -| Level | Font Size Token Name | Line Height Token Name | -| ------------------ | ------------------------ | -------------------------- | -| Minus 2 (smallest) | `typeRampMinus2FontSize` | `typeRampMinus2LineHeight` | -| Minus 1 | `typeRampMinus1FontSize` | `typeRampMinus1LineHeight` | -| Base (body) | `typeRampBaseFontSize` | `typeRampBaseLineHeight` | -| Plus 1 | `typeRampPlus1FontSize` | `typeRampPlus1LineHeight` | -| Plus 2 | `typeRampPlus2FontSize` | `typeRampPlus2LineHeight` | -| Plus 3 | `typeRampPlus3FontSize` | `typeRampPlus3LineHeight` | -| Plus 4 | `typeRampPlus4FontSize` | `typeRampPlus4LineHeight` | -| Plus 5 | `typeRampPlus5FontSize` | `typeRampPlus5LineHeight` | -| Plus 6 (largest) | `typeRampPlus6FontSize` | `typeRampPlus6LineHeight` | - ---- - -#### Sizing - -Here are the common sizing tokens you may want to adjust: - -- `controlCornerRadius`: Sets the corner radius used by controls with backplates.
- _Ex: Increase to `6px` for slightly rounder buttons and text fields._ -- `layerCornerRadius`: Sets the corner radius used layers like cards, flyouts, and dialogs.
- _Ex: Increase to `20px` for very round cards._ -- `density` (in process): A modifier used with sizing tokens `baseHeightMultiplier` and `baseHorizontalSpacingMultiplier`.
- _Ex: Set to `1` to increase control size or `-1` to decrease._ - -These are less common and more nuanced: - -- `baseHeightMultiplier`: This value, multiplied by `designUnit`, sets the base height of most controls. Works with adaptive `density` values. -- `baseHorizontalSpacingMultiplier` (future): This value, multiplied by `designUnit`, sets the internal horizontal padding of most controls. Works with adaptive `density` values. -- `designUnit`: The unit size of the design grid. Used to calculate height and spacing sizes for controls. - -#### Misc. - -Common: - -- `direction`: The primary document direction (LTR or RTL). - -Less common: - -- `strokeWidth`: Controls the width of the stroke of a component that has a stroke. -- `focusStrokeWidth`: Controls with width of the stroke of a component that has a stroke when it has document focus. -- `disabledOpacity`: The opacity of disabled controls. Careful with values that are too high as the control may no longer look disabled. There are no contrast requirements for a disabled control. - -### Adaptive color system - -The design tokens are built around an adaptive color system that provides some unique advantages: - -- Ensure text meets [WCAG](https://www.w3.org/WAI/standards-guidelines/wcag/) contrast requirements. -- Easily swap from light mode to dark, or anywhere in-between. -- Color theming through palette tinting. -- Perceptually uniform UI across background colors. - -To accomplish these goals, the web components make heavy use of algorithmic colors called Recipes. Recipes are a combination of an algorithm and input values that produce a desired result. Just as you can bake different types of cookies with different combinations of sugar, butter, flour, and salt, you can produce different design system treatments by altering recipe values (measurements) or algorithms (instructions). - -The current base recipes are closely related to their algorithm, but that's a convention and not a requirement. What follows is a list of the algorithms, which function on like-named values. For instance, `accentFill` relies on `accentFillRestDelta`, `accentFillHoverDelta`, `accentFillActiveDelta`, and `accentFillFocusDelta`. - -Recipes are currently used for color values, but they are not limited to that and their usage will be expanded soon. - -**To better visualize how this works, FAST built an application specifically for exploring the system. Check out [the Color Explorer.](https://color.fast.design/)** - -#### Common functionality - -Most color recipes are based on a `palette`. Currently there is built-in support for `accent` and `neutral` palettes. - -Most color recipes take a `reference` `Swatch`. This is a core concept of Adaptive UI which allows the recipes to vary based on the containing component's color. For instance, supporting a button with consistent treatment between light and dark modes is done with a single recipe. - -Many recipes are "stateful", meaning they support rest, hover, active, and focus states for a component. - -**"Fill"** means the recipe is intended to fill a larger area, commonly like a component backplate. - -**"Foreground"** means the recipe is intended for text, icons, or other lightweight decorations where you need or want to meet contrast requirements. - -**"Stroke"** means the recipe is intended for lines, either outline or divider. - -#### Accent algorithms - -##### accentFill - -Stateful. - -Relies on `textColor` and `contrastTarget` to find the closest colors from the supplied palette that can be used for component states. For instance, colors needed to support white text and a 14px font (which requires 4.5:1 contrast). - -##### accentForeground - -Stateful. - -Commonly for link text or icon. Also for smaller elements that might not show up well using `accentFill`, for instance if your accent color is dark purple and you support a dark mode interface. - -Like `accentFill` this relies on `textColor` and `contrastTarget` to find the closest colors from the supplied palette that can be used for component states. - -##### foregroundOnAccent - -Not stateful. - -Technically this doesn't _use_ the accent palette, but it's designed to be used _over_ the accent palette. This algorithm simply returns black or white based on the provided `contrastTarget`. It returns white if possible, as a common treatment for an accent button is white text over the accent color. - -#### Neutral algorithms - -##### neutralDivider - -Not stateful. - -Used for decorative dividers that do not need to meet contrast requirements. - -##### neutralFill - -Stateful. - -The most basic fill used for buttons or other components. - -##### neutralFillContrast - -Stateful. - -Often Used as a selected state or anywhere you want to draw attention. Meets contrast requirements with the containing background. - -##### neutralFillInput - -Stateful. - -Another basic fill, applied to input elements to allow easy differentiation from other components like buttons. - -##### neutralFillStealth - -Stateful. - -More subtle than `neutralFill` in that the resting state is transparent. Often used for low-priority features to draw less attention. - -##### neutralForeground - -Not stateful. - -Most common recipe, used for plain text or icons. - -##### neutralForegroundHint - -Not stateful. - -Used for subtle text. Meets 4.5:1 minimum contrast requirement. - -##### neutralStroke - -Stateful. - -Used for strong outline, either alone or with a fill. - -#### Layers - -The layer recipes are used for different sections of an app or site. They are designed to be able to stack, but that is not required. When stacked in sequence, the layers will lighten on top of each other. - -The key feature of layering is to support the primary container color for light or dark mode. This produces absolute colors based on the `baseLayerLuminance` value, which sets the luminance for layer one. This is any value between 0 for black or 1 for white. - -The difference between each layer is defined with `neutralFillLayerRestDelta`. - -Layers are not stateful. - -##### neutralFillLayer - -The only layer recipe that's relative to the container color instead of absolute. The most common example of this is a Card, which will be one layer color lighter than its container. - -##### neutralLayer1, neutralLayer2, neutralLayer3, and neutralLayer4 - -Absolute layer colors derived from and starting at `baseLayerLuminance`. Layer one is lightest and the values darken as the layer number increases. - -##### neutralLayerCardContainer - -A special layer to support experiences primarily built with cards, especially in light mode, so cards can be white and the container color can be one layer darker. - -##### neutralLayerFloating - -A special layer for floating layers, like flyouts or menus. It will be lighter than any other layers if possible, but will also be white in default light mode, as will neutral layer one. - -#### Adaptive Color "Don'ts" - -The adaptive color system lives entirely in JavaScript, emitting CSS custom properties for styling purposes where appropriate. This means that you should consider the CSS custom properties emitted by color Design Tokens to be immutable. If you declare the CSS custom property in CSS, the adaptive Color System is unable to know that has happened and components will render with incorrect colors, which can lead to accessibility issues. If you need to change the values for those CSS custom properties, set the value using the [DesignToken.setValueFor()](?path=/docs/design-system-design-tokens--page#setting-values) API. diff --git a/packages/web-components/src/_docs/getting-started/installation.stories.mdx b/packages/web-components/src/_docs/getting-started/installation.stories.mdx deleted file mode 100644 index 43ef8ca0405c7..0000000000000 --- a/packages/web-components/src/_docs/getting-started/installation.stories.mdx +++ /dev/null @@ -1,70 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -## Installation - -To install the component packages using NPM: - -```shell -npm install --save @fluentui/web-components -``` - -Or with yarn: - -```shell -yarn add @fluentui/web-components -``` - -## Registering & using the web components - -To use a Fluent UI Web Component as a custom element in HTML, the custom element must be registered. -Importing the component definition into your JavaScript bundle and registering it with a `DesignSystem` will register the custom element with the platform: - -```js -import { fluentButton, provideFluentDesignSystem } from '@fluentui/web-components'; - -provideFluentDesignSystem().register(fluentButton()); -``` - -As a shortcut, if you wish to easily register all available components, rather than registering each one, you can use the following pattern with either design system: - -```js -import { allComponents, provideFluentDesignSystem } from '@fluentui/web-components'; - -provideFluentDesignSystem().register(allComponents); -``` - -> When working with a tree-shaking supporting bundler such as Webpack or Rollup, you will want to import and register the individual components. This will ensure that any unused components are tree-shaken out of your builds. - -> Looking to integrate with a front-end framework or bundler? Check out [the integration docs](?path=/story/integrations-introduction--page). - -### From CDN - -A pre-bundled script that contains all APIs needed to use the components is available on CDN. You can use this script by adding [`type="module"`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) to the script element and then importing from the CDN. Here's how that would look: - -```html - - - - - - - -``` - -If you are using Fluent UI Web Components (or the FAST components) from the CDN, there is no need to register the components. The CDN script includes code that automatically sets up the design system and registers all the components. - -> The above CDN location points to the latest release of `@fluentui/web-components`. When you deploy your site or app, you should instead import the specific version you have developed and tested with. - -For simplicity, this documentation assumes the library has been installed from NPM, but you can always replace the import location with the CDN URL. - -## Add components - -With the components registered, add any component to the HTML. - -```html - -Hello world - -``` diff --git a/packages/web-components/src/_docs/getting-started/overview.stories.mdx b/packages/web-components/src/_docs/getting-started/overview.stories.mdx deleted file mode 100644 index c520be6a31bc1..0000000000000 --- a/packages/web-components/src/_docs/getting-started/overview.stories.mdx +++ /dev/null @@ -1,29 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -## The official Fluent UI Web Component library - -Microsoft's [Fluent UI Web Components](https://github.com/microsoft/fluentui/tree/master/packages/web-components) is designed to help you build Fluent web apps using extensible Web Components. The package composes the `@microsoft/fast-foundation` Web Component package and styles it with the [Fluent design language](https://github.com/microsoft/fluentui). -You can use these Web Components flexibly, either from [npm packages](https://www.npmjs.com/package/@fluentui/web-components), from the [CDN](https://unpkg.com/@fluentui/web-components), or you can bring it into your project to customize and extend it. See the [installation page](?path=/docs/getting-started-installation--page) for details. - -This storybook provides documentation and an interactive component playground from [Accordion](?path=/docs/components-accordion--accordion) to [TreeView](?path=/docs/components-tree-view--tree-view) to help you understand how to build with Fluent Web Components. - -- See the **COMPONENTS** _live_ in the side bar. -- See the [installation page](?path=/docs/getting-started-installation--page) for installation and getting started -- View the [integration examples](?path=/docs/integrations-introduction--page) to leverage the components in your front-end framework -- Check out the [GitHub repo](https://aka.ms/fluentui-web-components) for Web Components, part of the Fluent UI [monorepo](https://github.com/microsoft/fluentui) - -### What are Web Components? - -"Web Components" is an umbrella term that refers to a collection of web standards focused on enabling the creation of custom HTML elements. Some of the standards that are under the umbrella include the ability to define new HTML tags, plug into a standard component lifecycle, encapsulate HTML rendering and CSS, parameterize CSS, skin components, and more. Each of these platform features is defined by the W3C and has shipped in every major browser today. - -### How does Fluent UI Web Components leverage Web Components? - -Fluent UI Web Components is built directly on the W3C Web Component standards, and does not create its own component model. This allows our components to function the same as built-in, native HTML elements. You do not need a framework to use Fluent UI components but you can use them in combination with any framework or library of your choice. See [Integrations](?path=/docs/integrations-introduction--page) for more. - -### Joining the community - -Looking to get answers to questions or engage with us in realtime? Our community is most active [on Discord](https://discord.gg/FcSNfg4). Submit requests and issues on [GitHub](https://github.com/Microsoft/fast/issues/new/choose), or join us by contributing on [some good first issues via GitHub](https://github.com/Microsoft/fast/labels/community:good-first-issue). - -We look forward to building an amazing open source community with you! diff --git a/packages/web-components/src/_docs/integrations/angular.stories.mdx b/packages/web-components/src/_docs/integrations/angular.stories.mdx deleted file mode 100644 index a5321c08a37e6..0000000000000 --- a/packages/web-components/src/_docs/integrations/angular.stories.mdx +++ /dev/null @@ -1,122 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -Fluent UI Web Components integrate nicely with Angular. Let's take a look at how you can set up an Angular project, starting from scratch. - -## Setting up the Angular project - -First, you'll need to make sure that you have Node.js installed. You can learn more and download that [on the official site](https://nodejs.org/). - -With Node.js installed, you can run the following command to install the Angular CLI: - -```shell -npm install -g @angular/cli -``` - -With the CLI installed, you have access to the `ng` command-line interface. This can be used to create a new Angular project. For example, to create a new Angular App named "fluent-angular", you would use the following command: - -```shell -ng new fluent-angular -``` - -Follow the prompts, answering each question in turn. When the CLI completes, you should have a basic runnable Angular application. - -## Configuring packages - -Next, we'll install the Fluent packages, along with supporting libraries. To do that, run this command from your new project folder: - -```shell -npm install --save @fluentui/web-components @microsoft/fast-element lodash-es -``` - -## Using the components - -With all the basic pieces in place, let's run our app in dev mode with `ng serve --open`. The Angular CLI should build your project and make it available on localhost. Right now, it displays a basic welcome message, since we haven't added any code or interesting HTML. Let's change that. - -First, open your `src/main.ts` file and add the following code: - -```ts -import { provideFluentDesignSystem, fluentCard, fluentButton, fluentTextField } from '@microsoft/fluent-components'; - -provideFluentDesignSystem().register(fluentCard(), fluentButton(), fluentTextField()); -``` - -This code uses the Fluent Design System to register ``, `` and `` components. Once you save, the dev server will rebuild and refresh your browser. However, you still won't see anything. To get some UI showing up, we need to write some HTML that uses our components. Replace the HTML template in your `app/app.component.html` file with the following markup: - -```html - -

{{title}}

- - Click Me -
-``` - -Replace the code in your `app/app.component.ts` file contents with this: - -```ts -import { Component } from '@angular/core'; - -@Component({ - selector: 'app-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.css'], -}) -export class AppComponent { - title = 'fluent-angular'; - - exampleTextField = ''; - - onClick() { - console.log(this.exampleTextField); - } -} -``` - -To allow an NgModule to contain Non-Angular element names, add the following code in your `app/app.module.ts` file: - -```ts -import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; - -@NgModule({ - schemas: [ CUSTOM_ELEMENTS_SCHEMA ] -}) -``` - -To add a splash of style, replace the `app/app.component.css` file contents with this: - -```css -fluent-card { - padding: 16px; - display: flex; - flex-direction: column; -} - -fluent-text-field { - margin-bottom: 12px; -} - -h2 { - font-size: var(--type-ramp-plus-5-font-size); - line-height: var(--type-ramp-plus-5-line-height); -} - -fluent-card > fluent-button { - align-self: flex-end; -} -``` - -> **Note**: -> -> Third party controls require a ControlValueAccessor for writing a value and listening to changes on input elements. Add ngDefaultControl attribute to your component to have two-way binding working with FormControlDirective, FormControlName, or NgModel directives: - -```html - -``` - -Congratulations! You're now set up to use Fluent and Angular! diff --git a/packages/web-components/src/_docs/integrations/asp-net.stories.mdx b/packages/web-components/src/_docs/integrations/asp-net.stories.mdx deleted file mode 100644 index 115169b3753f0..0000000000000 --- a/packages/web-components/src/_docs/integrations/asp-net.stories.mdx +++ /dev/null @@ -1,89 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -Fluent UI Web Components work naturally with ASP.NET server-side development, by simply adding a script tag and using the custom HTML elements. Let's take a look at how to set things up. - -## Setting up the ASP.NET project - -First, you'll need to make sure that you have the .NET SDK installed. You can learn more and download that [on the official site](https://dotnet.microsoft.com/download). - -With the SDK installed, you have access to the `dotnet` command-line interface. This can be used to create a new ASP.NET project. For example, to create a new ASP.NET Core MVC Web App named "fluent-aspnet", you would use the following command: - -```shell -dotnet new mvc -o fluent-aspnet -``` - -Create a project using the command above if you don't already have one. When the CLI completes, you should have a basic runnable ASP.NET Core MVC application. - -## Configuring scripts - -Now that we've got our basic project setup, we need to add our web components script and update ASP.NET accordingly. You can either add the script from our CDN directly, or you can install it with NPM and then add that. - -To add a CDN script for `fluent-components` use the following markup: - -```html - -``` - -The best place to put this is typically in your `_Layout.cshtml` file in the script section at the bottom of the ``. - -If you wish to leverage NPM instead, run the following command: - -```shell -npm install --save @fluentui/web-components -``` - -You can locate the single file script build in the following location: - -```shell -node_modules/@fluentui/web-components/dist/fluent-components.min.js -``` - -Copy this to your `wwwroot/js` folder and reference it with a script tag as described above. - -Should you wish to go one step further and leverage a client-side bundler, such as Webpack, there is some additional setup to integrate with ASP.NET that is beyond the scope of this tutorial. Basic Webpack instructions for Fluent UI Web Components can be found [here](./webpack). The most important detail with respect to Fluent UI Web Components is that you'll want to install a few more packages. Use the following command if this is your preferred setup: - -```shell -npm install --save @fluentui/web-components @microsoft/fast-element lodash-es -``` - -In this case, because Webpack can tree-shake unused components, you'll also want to be sure to register the components you want to use somewhere in your own JavaScript code. See [our Webpack guide](./webpack) for an example. - -## Using the components - -With your script tag added (or your client bundle in place), you can use any component in any of your views. For example, you could put something like this in your `Index.cshtml` file: - -```html -@{ ViewData["Title"] = "Home Page"; } - - -

@ViewData["Title"]

- Click Me -
-``` - -For a splash of style, add the following to your `wwwroot/css/site.css` file: - -```css -:not(:defined) { - visibility: hidden; -} - -fluent-card { - padding: 16px; - display: flex; - flex-direction: column; -} - -h2 { - font-size: var(--type-ramp-plus-5-font-size); - line-height: var(--type-ramp-plus-5-line-height); -} - -#button { - align-self: flex-end; -} -``` - -Congratulations! You're now set up to use Fluent UI Web Components with ASP.NET. You can use more components, build your own components, and when you are ready, build and deploy your website or app to production. diff --git a/packages/web-components/src/_docs/integrations/aurelia.stories.mdx b/packages/web-components/src/_docs/integrations/aurelia.stories.mdx deleted file mode 100644 index 016624b310e02..0000000000000 --- a/packages/web-components/src/_docs/integrations/aurelia.stories.mdx +++ /dev/null @@ -1,291 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -FAST works flawlessly with both Aurelia 1 and Aurelia 2, with full integration into the binding engine and component model. Let's take a look at how you can set up an Aurelia project, starting from scratch. - -## Aurelia 2 - -### Setting up the Aurelia 2 project - -First, you'll need to make sure that you have Node.js installed. You can learn more and download that [on the official site](https://nodejs.org/). - -With Node.js installed, you can run the following command to create a new Aurelia 2 project: - -```shell -npx makes Aurelia -``` - -Follow the prompts, answering each question in turn. It is recommended that you select the "Default TypeScript Aurelia 2 App" when prompted unless you have previous experience with the CLI. Be sure to choose to install dependencies when asked. - -When the CLI completes, you should have a basic runnable Aurelia 2 application. - -### Configuring packages - -Next, we'll install the FAST packages, along with supporting libraries. To do that, run this command from your new project folder: - -```shell -npm install --save @fluentui/web-components @microsoft/fluent-element lodash-es -``` - -### Using the components - -With all the basic pieces in place, let's run our app in dev mode with `npm start`. Webpack should build your project and open your default browser with your `index.html` page. Right now, it should only have a hello message, since we haven't added any code or interesting HTML. Let's change that. - -First, open your `src/main.ts` file and add the following code: - -```ts -import { provideFASTDesignSystem, fastCard, fastButton } from '@fluentui/web-components'; - -provideFASTDesignSystem().register(fastCard(), fastButton()); -``` - -This code uses the FAST Design System to register the `` and `` components. Once you save, the dev server will rebuild and refresh your browser. However, you still won't see anything. To get some UI showing up, we need to write some HTML that uses our components. Replace your `my-app.html` file with the following markup: - -```html - -

${message}

- Click Me -
-``` - -Replace your `my-app.ts` with this: - -```ts -export class MyApp { - public message = 'Hello World!'; - - onClick() { - console.log('clicked!'); - } -} -``` - -To add a splash of style, replace your `my-app.css` content with this: - -```css -fluent-card { - padding: 16px; - display: flex; - flex-direction: column; -} - -h2 { - font-size: var(--type-ramp-plus-5-font-size); - line-height: var(--type-ramp-plus-5-line-height); -} - -fluent-card > fluent-button { - align-self: flex-end; -} -``` - -### Enabling two-way bindings - -Aurelia knows by default how to listen for changes in native elements. Now we need to teach it how to listen for changes in FAST elements. You can do so by [extending its templating syntax](https://docs.aurelia.io/examples/integration/ms-fast). - -You can either use a [wrapper](https://www.npmjs.com/package/aurelia-fast-adapter) developed by the community or teach Aurelia manually: - -### Import and register `aurelia-fast-adapter` - -Start by installing the adapter - -```ts -npm install aurelia-fast-adapter -``` - -and then simply register it from your `src/main.ts`: - -```ts -// src/main.ts - -import { FASTAdapter } from 'aurelia-fast-adapter'; - -Aurelia.register(FASTAdapter) // add this line - // other registrations... - .start(); -``` - -If you use FAST in its default configuration that's all you need to do. But if you changed the prefix of your components to something else, you can customize the adapter as such: - -```ts -// src/main.ts - -import { FASTAdapter } from 'aurelia-fast-adapter'; - -Aurelia - .register(FASTAdapter.customize({withPrefix: 'my-custom-prefix'}) // customized with prefix - .start(); -``` - -Also, in case you have local components that require two-way binding, you can adjust the adapter before to register it as such: - -```ts -// src/main.ts - -import { FASTAdapter } from 'aurelia-fast-adapter'; - -// this line will tell the adapter that it must use two-way binding on the component and use this two-way binding on the `value` property. It's possible to add several properties at once if necessary -FASTAdapter.tags['DATE-FIELD'] = ['value']; - -Aurelia - .register(FASTAdapter.customize({withPrefix: 'my-custom-prefix'}) - .start(); -``` - -Congratulations! You're now set up to use FAST and Aurelia 2! - -### Manually teach Aurelia 2 about two-way binding: - -If the example doesn't seem obvious, the following prerequisite reads are recommended: - -- [extending Aurelia templating syntax](https://docs.aurelia.io/app-basics/extending-templating-syntax) - -The following is a code example of how to teach Aurelia to work seamlessly with Microsoft FAST. - -```typescript -import { AppTask, IContainer, IAttrMapper, NodeObserverLocator } from 'aurelia'; - -Aurelia.register( - AppTask.beforeCreate(IContainer, container => { - const attrMapper = container.get(IAttrMapper); - const nodeObserverLocator = container.get(NodeObserverLocator); - attrMapper.useTwoWay((el, property) => { - switch (el.tagName) { - case 'FAST-SLIDER': - case 'FAST-TEXT-FIELD': - case 'FAST-TEXT-AREA': - return property === 'value'; - case 'FAST-CHECKBOX': - case 'FAST-RADIO': - case 'FAST-RADIO-GROUP': - case 'FAST-SWITCH': - return property === 'checked'; - case 'FAST-TABS': - return property === 'activeid'; - default: - return false; - } - }); - - // Teach Aurelia what events to use to observe properties of elements. - // Because FAST components all use a single change event to notify, - // we can use a single common object - const valuePropertyConfig = { events: ['input', 'change'] }; - nodeObserverLocator.useConfig({ - 'FAST-CHECKBOX': { - checked: valuePropertyConfig, - }, - 'FAST-RADIO': { - checked: valuePropertyConfig, - }, - 'FAST-RADIO-GROUP': { - value: valuePropertyConfig, - }, - 'FAST-SLIDER': { - value: valuePropertyConfig, - }, - 'FAST-SWITCH': { - checked: valuePropertyConfig, - }, - 'FAST-TABS': { - activeid: valuePropertyConfig, - }, - 'FAST-TEXT-FIELD': { - value: valuePropertyConfig, - }, - 'FAST-TEXT-AREA': { - value: valuePropertyConfig, - }, - }); - }), -); -``` - -## Aurelia 1 - -### Setting up the Aurelia 1 project - -First, you'll need to make sure that you have Node.js installed. You can learn more and download that [on the official site](https://nodejs.org/). - -With Node.js installed, you can run the following command to install the Aurelia 1 CLI: - -```shell -npm install -g aurelia-cli -``` - -And then use the CLI like this: - -```shell -au new fast-aurelia -``` - -Follow the prompts, answering each question in turn. It is recommended that you select the "Default TypeScript App" when prompted unless you have previous experience with the CLI. Be sure to choose to install dependencies when asked. - -When the CLI completes, you should have a basic runnable Aurelia 1 application. - -### Configuring packages - -Next, we'll install the FAST packages, along with supporting libraries. To do that, run this command from your new project folder: - -```shell -npm install --save @fluentui/web-components @microsoft/fluent-element lodash-es -``` - -### Using the components - -With all the basic pieces in place, let's run our app in dev mode with `npm start`. Webpack should build your project and make it available at `http://localhost:8080/`. If you visit this address it should only have a hello message, since we haven't added any code or interesting HTML. Let's change that. - -First, open your `src/main.ts` file and add the following code: - -```ts -import { provideFASTDesignSystem, fastCard, fastButton } from '@fluentui/web-components'; - -provideFASTDesignSystem().register(fastCard(), fastButton()); -``` - -This code uses the FAST Design System to register the `` and `` components. Once you save, the dev server will rebuild and refresh your browser. However, you still won't see anything. To get some UI showing up, we need to write some HTML that uses our components. Replace your `app.html` file with the following markup: - -```html - -``` - -Replace your `app.ts` with this: - -```ts -export class App { - public message: string = 'Hello World!'; - - onClick() { - console.log('clicked!'); - } -} -``` - -To add a splash of style, add the following to your `app.html` template: - -```html - -``` - -Congratulations! You're now set up to use FAST and Aurelia 1! diff --git a/packages/web-components/src/_docs/integrations/blazor.stories.mdx b/packages/web-components/src/_docs/integrations/blazor.stories.mdx deleted file mode 100644 index 6cf58fe826d3b..0000000000000 --- a/packages/web-components/src/_docs/integrations/blazor.stories.mdx +++ /dev/null @@ -1,118 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -FAST works seamlessly with Blazor, including integration with Blazor's binding engine and components. Let's take a look at how to set things up. - -## Setting up the Blazor project - -First, you'll need to make sure that you have the .NET SDK installed. You can learn more and download that [on the official site](https://dotnet.microsoft.com/download). - -With the SDK installed, you have access to the `dotnet` command-line interface. This can be used to create a new Blazor project. For example, to create a new Blazor App named "fluent-blazor", you would use the following command: - -```shell -dotnet new blazorwasm -o fluent-blazor -``` - -Create a project using the command above if you don't already have one. When the CLI completes, you should have a basic runnable Blazor application. For more information on setting up and using Blazor, [see the official Blazor Getting Started guide](https://docs.microsoft.com/en-us/aspnet/core/blazor/get-started). - -## Configuring scripts - -Now that we've got our basic project setup, we need to add our web components script and update Blazor accordingly. You can either add the script from our CDN directly, or you can install it with NPM and then add that. - -To add a CDN script for `fluent-components` use the following markup: - -```html - -``` - -The best place to put this is typically in your `index.html` file in the script section at the bottom of the ``. - -> **Note**: -> -> If you are setting up FAST on a Blazor Server project, you will need to escape the `@` character by repeating it in the source link. For more information check out the [Razor Pages syntax documentation](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor#razor-syntax). - -If you wish to leverage NPM instead, run the following command: - -```shell -npm install --save @fluentui/web-components -``` - -You can locate the single file script build in the following location: - -```shell -node_modules/@fluentui/web-components/dist/fluent-components.min.js -``` - -Copy this to your `wwwroot/script` folder and reference it with a script tag as described above. - -## Using the components - -With your script tag added, you can use any component in any of your views. For example, you could put something like this in your `Index.razor` file: - -```html -@page "/" - - -

Hello World!

- Click Me -
-``` - -For a splash of style, add the following to your `wwwroot/css/app.css` file: - -```css -fluent-card { - padding: 16px; - display: flex; - flex-direction: column; -} - -h2 { - font-size: var(--type-ramp-plus-5-font-size); - line-height: var(--type-ramp-plus-5-line-height); -} - -fluent-card > fluent-button { - align-self: flex-end; -} -``` - -If you are using the .NET CLI, you can run your project with the following command from the project folder: - -```shell -dotnet watch run -``` - -Congratulations! You're now set up to use FAST with Blazor! - -## Using the Fluent UI Web Components - -FAST has special Blazor support for Microsoft's Fluent UI Web Components. To leverage the Fluent UI Design System, you'll need to make a few modifications to your project. - -First, update the script tag to point to the Fluent UI Web Components. - -```html - -``` - -Second, change the `fluent-` prefix to `fluent-` in any CSS selectors. - -Third, you will want to install [the official Nuget package for Fluent UI](https://www.nuget.org/packages/Microsoft.Fast.Components.FluentUI/). You can use the following command: - -```shell -dotnet add package Microsoft.Fast.Components.FluentUI -``` - -With this package installed, you can switch the HTML over to Blazor components. Here's an example: - -```html -@page "/" @using Microsoft.Fast.Components.FluentUI - - -

Hello World!

- Click Me -
-``` - -To report issues or provide feedback on `Microsoft.Fast.Components.FluentUI`, please visit [the microsoft/fast-blazor repository](https://github.com/microsoft/fast-blazor). diff --git a/packages/web-components/src/_docs/integrations/ember.stories.mdx b/packages/web-components/src/_docs/integrations/ember.stories.mdx deleted file mode 100644 index 329691d130732..0000000000000 --- a/packages/web-components/src/_docs/integrations/ember.stories.mdx +++ /dev/null @@ -1,107 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -Fluent UI Web Components and Ember work great together. - -## Setting up the Ember project - -First, you'll need to make sure that you have Node.js installed. You can learn more and download that [on the official site](https://nodejs.org/). - -With Node.js installed, you can run the following command to install the Ember CLI: - -```shell -npm install -g ember-cli -``` - -With the CLI installed, you have access to the `ember` command-line interface. This can be used to create a new Ember project. For example, to create a new Ember App named "fluent-ember", you would use the following command: - -```shell -ember new fluent-ember --lang en -``` - -When the CLI completes, you should have a basic runnable Ember application. - -## Configuring packages - -Next, we'll install the Fluent UI Web Component packages, along with supporting libraries. To do that, run this command from your new project folder: - -```shell -npm install --save @fluentui/web-components @microsoft/fast-element lodash-es -``` - -## Using the components - -With all the pieces in place, let's run our app in dev mode with `npm start`. The Ember CLI should build your project and make it available on localhost. Right now, it displays a basic welcome message, since we haven't added any code or interesting HTML. Let's change that. - -First, open your `app/app.js` file and add the following code: - -```ts -import { provideFluentDesignSystem, fluentCard, fluentButton, fluentTextField } from '@fluentui/web-components'; - -provideFluentDesignSystem().register(fluentCard(), fluentButton(), fluentTextField()); -``` - -This code uses the Fluent Design System to register the ``, ``, and `` components. Once you save, the dev server will rebuild and refresh your browser. However, you still won't see anything. Open your `application.hbs` file and replace the `` component with the following HTML and then save again. - -```html -

Fluent Ember

- - Click Me -
-``` - -Now you should see the Fluent UI Web Components displayed in your Ember application. - -Next, let's improve this by refactoring it into a component. Stop the CLI and run the following command to scaffold a new Ember component that will be called `fluent-demo`. - -```ts -ember generate component fluent-demo -``` - -Copy your original HTML above and use it to replace the HTML in your `app/components/fluent-demo.hbs` file. Next replace that same HTML in `templates/application.hbs` file with the following Ember component use: - -```html - -``` - -Run `npm start` again and you should see the same output, but now we have moved our web components into a `fluentDemo` Ember component. - -Let's take it a little further. Create a `fluent-demo.js` file in the same folder as your `fluent-demo.hbs` file and paste the following code: - -```js -import Component from '@glimmer/component'; -import { action } from '@ember/object'; -import { tracked } from '@glimmer/tracking'; - -export default class FluentDemoComponent extends Component { - @tracked exampleTextField = ''; - - @action - onClick() { - console.log(this.exampleTextField); - } - - @action - onInput(event) { - this.exampleTextField = event.target.value; - } -} -``` - -Next, update the `fluent-demo.hbs` file with the following HTML: - -```html - -

fluent Ember

- - Click Me -
-``` - -With this code in place, you now have Fluent UI Web Components fully binding to data and handling user interactions, all from inside an Ember component. - -Congratulations! You're now set up to use Fluent and Ember! diff --git a/packages/web-components/src/_docs/integrations/introduction.stories.mdx b/packages/web-components/src/_docs/integrations/introduction.stories.mdx deleted file mode 100644 index 1255f40b80b54..0000000000000 --- a/packages/web-components/src/_docs/integrations/introduction.stories.mdx +++ /dev/null @@ -1,18 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -## Introduction to Integrations - -The Fluent UI Web Component libraries, composed from [FAST Components](https://www.fast.design/), can be used on their own to build modern web sites and applications, but are also designed to be used in combination with a wide variety of existing technologies. -This section is dedicated to helping you get Fluent UI web components working with your preferred stack. - -- [Angular](?path=/story/integrations-angular--page) -- [ASP.NET](?path=/story/integrations-asp-net--page) -- [Aurelia](?path=/story/integrations-aurelia--page) -- [Blazor](?path=/story/integrations-blazor--page) -- [React](?path=/story/integrations-react--page) -- [Vue](?path=/story/integrations-vue--page) -- [Webpack](?path=/story/integrations-webpack--page) - -Not seeing an integration for your preferred technology? We'd be happy to work with you to add it. Feel free to kick off a discussion by [opening an issue on the FAST component GitHub](https://github.com/microsoft/fast/issues). diff --git a/packages/web-components/src/_docs/integrations/react.stories.mdx b/packages/web-components/src/_docs/integrations/react.stories.mdx deleted file mode 100644 index 81fabafb26e6b..0000000000000 --- a/packages/web-components/src/_docs/integrations/react.stories.mdx +++ /dev/null @@ -1,209 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -Fluent UI Web Components can be used in React applications. Let's take a look at how you can set up a project, starting from scratch. - -## Setting up the React project - -First, you'll need to make sure that you have Node.js >= 8.2 and npm >= 5.6 installed. You can learn more and download that [on the official site](https://nodejs.org/). - -With Node.js installed, you can use [create-react-app](https://reactjs.org/docs/create-a-new-react-app.html#create-react-app) to create a new React project. - -```shell -npx create-react-app fluent-app -``` - -## Configuring packages - -Next, we'll install the Fluent UI Web Component package, along with supporting FAST libraries. To do that, run this command from your new project folder: - -```shell -npm install --save @fluentui/web-components @microsoft/fast-foundation @microsoft/fast-element @microsoft/fast-react-wrapper -``` - -## Configure create-react-app - -[create-react-app](https://reactjs.org/docs/create-a-new-react-app.html#create-react-app) ships with an [eslint](https://eslint.org/) rule that makes working with Fluent UI Web Components difficult. There are two changes that will need to be made in the `package.json`: - -**Set the EXTEND_ESLINT environment variable in start, build, and test scripts** - -```jsonc -{ - //... - "scripts": { - "start": "EXTEND_ESLINT=true react-scripts start", - "build": "EXTEND_ESLINT=true react-scripts build", - "test": "EXTEND_ESLINT=true react-scripts test" - } - // ... -} -``` - -**Override the `eslintConfig` field to turn off the 'no-unused-expressions' rule** - -```jsonc -{ - //.. - "eslintConfig": { - "extends": "react-app", - "rules": { - "no-unused-expressions": "off" - } - } - //.. -} -``` - -See [configuring eslint](https://create-react-app.dev/docs/setting-up-your-editor#experimental-extending-the-eslint-config) for more information. - -## Using the components - -With all the basic pieces in place, let's run our app in dev mode with `npm start`. Right now, it displays the React logo and some editing instructions, since we haven't added any code or interesting HTML. Let's change that. - -First, open your `src/app.js` file and add the following code: - -With all the basic pieces in place, let's run our app in dev mode with `npm start`. Right now, it displays the React logo and some editing instructions, since we haven't added any code or interesting HTML. Let's change that. - -First, open your `src/app.js` file and add the following code: - -```js -import { provideFluentDesignSystem, fluentCard, fluentButton } from '@fluentui/web-components'; -import { provideReactWrapper } from '@microsoft/fast-react-wrapper'; -import React from 'react'; - -const { wrap } = provideReactWrapper(React, provideFluentDesignSystem()); - -export const FluentCard = wrap(fluentCard()); -export const FluentButton = wrap(fluentButton()); -``` - -This code uses the Fluent Design System to register the `` and `` components while automatically wrapping them into React components. Once you save, the dev server will rebuild and refresh your browser. However, you still won't see anything. To get some UI showing up, we need to write some HTML that uses our components. Replace the App component in your `src/app.js` file with the following: - -```jsx -function App() { - return ( - -

Fluent React

- console.log('clicked')}> - Click Me - -
- ); -} -``` - -To add a splash of style, add the following to the `src/App.css`: - -```css -fluent-card { - padding: 16px; - display: flex; - flex-direction: column; -} - -h2 { - font-size: var(--type-ramp-plus-5-font-size); - line-height: var(--type-ramp-plus-5-line-height); -} - -fluent-card > fluent-button { - align-self: flex-end; -} -``` - -Congratulations! You're now set up to use Fluent and React! - -## Using the React Wrapper - -Above, we leveraged the `@microsoft/fast-react-wrapper` library to enable seamless integration of Fluent Components. There are a few additional ways to use this API for different web component scenarios. - -### Wrapping Design System Components - -Previously, you've seen that we can wrap a Design System component by passing its registration function to the `wrap` method as follows: - -```ts -const { wrap } = provideReactWrapper(React, provideFluentDesignSystem()); - -export const FluentButton = wrap(fluentButton()); -``` - -This code creates a wrapper that is configured with a React-compatible API and a Design System instance. When passing a Design System as the second parameter, you can then pass component registration functions to the `wrap` helper. The helper will both register the web component with the Design System and wrap it in a type-safe React component, all with a single call. - -Alternatively, you can skip providing the Design System to the wrapper, and use the generated registry to manually register all previously wrapped components. - -```ts -const { wrap, registry } = provideReactWrapper(React); - -export const FluentButton = wrap(fluentButton()); - -provideFluentDesignSystem().register(registry); -``` - -The final option is to handle everything by hand: - -```ts -const { wrap } = provideReactWrapper(React); - -export const FluentButton = wrap(fluentButton()); - -provideFluentDesignSystem().register(fluentButton()); -``` - -### Configuring Custom Events - -If the wrapped component uses custom events that you intend to use from React, you will need to manually configure a mapping from React event name to the native event name. Here's an example of what that would look like if you wanted to leverage the FAST MenuItem's `expanded-change` event: - -```ts -const { wrap } = provideReactWrapper(React, provideFluentDesignSystem()); - -export const FluentMenuItem = wrap(fluentMenuItem(), { - events: { - onExpandedChange: 'expanded-change', - }, -}); -``` - -## Additional Notes - -### create-react-app - -FAST makes use of decorators to define components. At this time, `create-react-app` [does not support decorators](https://create-react-app.dev/docs/can-i-use-decorators/). This won't be a problem when using components _imported_ from FAST because they have already been transpiled by TypeScript - but to _create_ components in a `create-react-app` application you'll need to do one of the following: - -- [Define components without decorators](https://fast.design/docs/fast-element/defining-elements#working-without-decorators) -- [Eject](https://create-react-app.dev/docs/available-scripts#npm-run-eject)`create-react-app` and change Babel to support decorators -- Use an intermediary like [react-app-rewired](https://www.npmjs.com/package/react-app-rewired) - -### Data Binding - -#### HTML Attributes - -React is capable of rendering custom HTML elements and binding data to them, but it is beneficial to understand _how_ React does this. React will apply all _props_ to a custom HTML element as _HTML attributes_ - including non-primitive types such as arrays and objects. Where some UI libraries provide binding syntaxes to distinguish setting properties, attributes, and events, React does not. This means that it can be very easy to end up with `my-prop="[object Object]"` in your HTML. React is exploring solutions [in this issue](https://github.com/facebook/react/issues/11347). See the section on [interop layers](#interop-layers-skatejsval-and-reactify-wc) for a work-around for this issue. - -#### Custom events - -React's synthetic eventing system comes with an unfortunate side-effect of being incapable of declaratively applying [`CustomEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) listeners. [interop layers](#interop-layers-skatejsval-and-reactify-wc) can be used to address this issue. Alternatively, a `ref` can be used on the custom element to imperatively apply the event listener to the HTML element directly. - -#### Interop layers: @skatejs/val and reactify-wc - -[@skatejs/val](https://github.com/skatejs/val) is a small library that wraps React's `createElement` function and provides the ability direct React _props_ explicitly to HTML attributes, DOM properties, or to declarative event listeners. - -Another good option is [reactify-wc](https://github.com/BBKolton/reactify-wc). It provides similar capabilities as `@skatejs/val` but does so by creating component wrappers. - -### TypeScript and TSX support - -If you're using TypeScript, you'll need to augment the `JSX.IntrinsicElements` interface to use custom elements in TSX. To do so, create a `custom-elements.d.ts` file in your source directory and add the following: - -```ts -// custom-elements.d.ts -declare namespace JSX { - interface IntrinsicElements { - /** - * React.DetailedHTMLProps, HTMLElement> allows setting standard HTML attributes on the element - */ - 'my-element': React.DetailedHTMLProps, HTMLElement> & { - 'my-attribute-name': string; - }; - } -} -``` diff --git a/packages/web-components/src/_docs/integrations/vue.stories.mdx b/packages/web-components/src/_docs/integrations/vue.stories.mdx deleted file mode 100644 index 7c7894e10e773..0000000000000 --- a/packages/web-components/src/_docs/integrations/vue.stories.mdx +++ /dev/null @@ -1,97 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -Fluent UI Web Components work great with Vue. Let's take a look at how you can set up a Vue project, starting from scratch. - -## Setting up the Vue project - -First, you'll need to make sure that you have Node.js installed. You can learn more and download that [on the official site](https://nodejs.org/). - -With Node.js installed, you can run the following command to install the Vue CLI: - -```shell -npm install -g @vue/cli -``` - -With the CLI installed, you have access to the `vue` command-line interface. This can be used to create a new Vue project. For example, to create a new Vue App named "fluent-vue", you would use the following command: - -```shell -vue create fluent-vue -``` - -When prompted to select options, choose "Manually select features". Follow the prompts, answering each question in turn. It is recommended that you select "TypeScript" when prompted. - -When the CLI completes, you should have a basic runnable Vue application. - -## Configuring packages - -Next, we'll install the Fluent UI Web Component packages, along with supporting libraries. To do that, run this command from your new project folder: - -```shell -npm install --save @fluentui/web-components @microsoft/fast-element lodash-es -``` - -## Using the components - -With all the basic pieces in place, let's run our app in dev mode with `npm run serve`. The Vue CLI should build your project and make it available on localhost. Right now, it displays a basic welcome message, since we haven't added any code or interesting HTML. Let's change that. - -First, open your `src/main.ts` file and add the following code: - -```ts -import { provideFluentDesignSystem, fluentCard, fluentButton } from '@fluentui/web-components'; - -provideFluentDesignSystem().register(fluentCard(), fluentButton()); -``` - -This code uses the Fluent Design System to register the `` and `` components. Once you save, the dev server will rebuild and refresh your browser. However, you still won't see anything. To get some UI showing up, we need to write some HTML that uses our components. Replace the HTML template in your `components/HelloWorld.vue` file with the following markup: - -```html - -``` - -Replace your script tag with this: - -```html - -``` - -To add a splash of style, replace the `style` tag with this: - -```html - -``` - -Congratulations! You're now set up to use Fluent and Vue! diff --git a/packages/web-components/src/_docs/integrations/webpack.stories.mdx b/packages/web-components/src/_docs/integrations/webpack.stories.mdx deleted file mode 100644 index c538e6abf589c..0000000000000 --- a/packages/web-components/src/_docs/integrations/webpack.stories.mdx +++ /dev/null @@ -1,202 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -Fluent UI Web Components work great with TypeScript and Webpack, using a fairly standard setup. Let's take a look at how you can set up a TypeScript+Webpack project, starting from scratch. - -## Setting up the package - -First, let's make a directory for our new project. From the terminal: - -```shell -mkdir fluent-webpack -``` - -Next, let's move into that directory, where we'll set up our project: - -```shell -cd fluent-webpack -``` - -From here, we'll initialize npm: - -```shell -npm init -``` - -Follow the prompts from npm, answering each question in turn. You can always accept the defaults at first and then make changes later in the package.json file. - -Next, we'll install the Fluent packages, along with supporting libraries. To do that, run this command: - -```shell -npm install --save @fluentui/web-components @microsoft/fast-element lodash-es -``` - -We also need to install the Webpack build tooling: - -```shell -npm install --save-dev clean-webpack-plugin ts-loader typescript webpack webpack-cli webpack-dev-server -``` - -## Adding configuration and source - -Now that we've got our basic package and dependencies set up, let's create some source files and get things configured. Since we're going to be writing a bit of code, now is a great time to involve a code editor in the process. If you're looking for a great editor for TypeScript and front-end in general, we highly recommend [VS Code](https://code.visualstudio.com/). - -Open the `fluent-webpack` folder in your favorite editor. You should see your `package.json` along with a `package-lock.json` and a `node_modules` folder. - -First, let's create a `src` folder where we'll put all our TypeScript code. In the `src` folder, add a `main.ts` file. You can leave the file empty for now. We'll come back it in a bit. - -Next, in the root of your project folder, add a `tsconfig.json` file to configure the TypeScript compiler. Here's an example starter config that you can put into that file: - -```json -{ - "compilerOptions": { - "pretty": true, - "target": "ES2015", - "module": "ES2015", - "moduleResolution": "node", - "importHelpers": true, - "experimentalDecorators": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "noEmitOnError": true, - "strict": true, - "outDir": "dist/build", - "rootDir": "src", - "lib": ["dom", "esnext"] - }, - "include": ["src"] -} -``` - -You can learn more about `tsconfig.json` options in [the official TypeScript documentation](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). - -Next, create a `webpack.config.js` file in the root of your project folder with the following source: - -```js -const { CleanWebpackPlugin } = require('clean-webpack-plugin'); -const path = require('path'); - -module.exports = function (env, { mode }) { - const production = mode === 'production'; - return { - mode: production ? 'production' : 'development', - devtool: production ? 'source-map' : 'inline-source-map', - entry: { - app: ['./src/main.ts'], - }, - output: { - filename: 'bundle.js', - publicPath: '/', - }, - resolve: { - extensions: ['.ts', '.js'], - modules: ['src', 'node_modules'], - }, - devServer: { - port: 9000, - historyApiFallback: true, - open: !process.env.CI, - devMiddleware: { - writeToDisk: true, - }, - static: { - directory: path.join(__dirname, './'), - }, - }, - plugins: [new CleanWebpackPlugin()], - module: { - rules: [ - { - test: /\.ts$/i, - use: [ - { - loader: 'ts-loader', - }, - ], - exclude: /node_modules/, - }, - ], - }, - }; -}; -``` - -This setup uses `ts-loader` to process TypeScript. It will also enable both a production mode and a development mode that watches your source, recompiling and refreshing your browser as things change. You can read more about Webpack configuration in [the official Webpack documentation](https://webpack.js.org/). - -To enable easy execution of both our production and development builds, let's add some script commands to our `package.json` file. Find the `scripts` section of your `package.json` file and add the following two scripts: - -```json -"scripts": { - "build": "webpack --mode=production", - "dev": "webpack serve" -} -``` - -The `build` script will build your TypeScript for production deployment while the `dev` script will run the development web server so you can write code and see the results in your browser. You can run these scripts with `npm run build` and `npm run dev` respectively. - -To complete our setup, we need to add an `index.html` file to the root of our project. We'll start with some basic content as follows: - -```html - - - - - Fluent Webpack - - - - - -``` - -There's nothing special about the HTML yet other than the `script` tag in the `body` that references the `bundle.js` file that our Webpack build will produce. - -## Using the components - -With all the basic pieces in place, let's run our app in dev mode with `npm run dev`. Webpack should build your project and open your default browser with your `index.html` page. Right now, it should be blank, since we haven't added any code or interesting HTML. Let's change that. - -First, open your `src/main.ts` file and add the following code: - -```ts -import { provideFluentDesignSystem, fluentCard, fluentButton } from '@fluentui/web-components'; - -provideFluentDesignSystem().register(fluentCard(), fluentButton()); -``` - -This code uses the Fluent Design System to register the `` and `` components. Once you save, the dev server will rebuild and refresh your browser. However, you still won't see anything. To get some UI showing up, we need to write some HTML that uses our components. Replace the contents of the `` in your `index.html` file with the following markup: - -```html - - -

Hello World!

- Click Me -
- - - -``` - -After saving your `index.html` file, refresh your browser and you should see a card with text and a button. - -Congratulations! You're now set up to use Fluent, TypeScript, and Webpack. You can import and use more components, build your own components, and when you are ready, build and deploy your website or app to production. diff --git a/packages/web-components/src/_docs/resources/browsersupport.stories.mdx b/packages/web-components/src/_docs/resources/browsersupport.stories.mdx deleted file mode 100644 index 53e077e14c182..0000000000000 --- a/packages/web-components/src/_docs/resources/browsersupport.stories.mdx +++ /dev/null @@ -1,19 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -## Browser Support - -The following browsers have native support for the Web Components features used by `fast-element` and our components: - -- Microsoft Edge 79+ -- Mozilla Firefox 63+ -- Google Chrome 67+ -- Apple Safari 10.1+ -- Opera 41+ -- iOS Safari 10.3+ -- Android Browser 81+ -- Opera Mobile 46+ -- Chrome for Android 81+ -- Firefox for Android 68+ -- Samsung Internet 6.2+x diff --git a/packages/web-components/src/_docs/resources/faq.stories.mdx b/packages/web-components/src/_docs/resources/faq.stories.mdx deleted file mode 100644 index 6c4f4d42f1232..0000000000000 --- a/packages/web-components/src/_docs/resources/faq.stories.mdx +++ /dev/null @@ -1,29 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -## FAQ - -### What's the difference between Fluent and FAST? - -Fluent is Microsoft's design language, independent of any particular implementation technology. FAST is an agnostic tech stack that enables implementing web components, design systems, and apps. `fast-element` is the lowest level of FAST, providing core features for building performant web components. `fast-foundation` is layered on top of `fast-element` and provides primarily two things: core features for building design systems, and a core set of components that are design-system-independent. With `fast-foundation` you can implement any design system. For example, you could implement Fluent Design, Material Design, Lightning Design, Bootstrap, etc. Once the design system is implemented, it can connect with any component built with `fast-element` or `fast-foundation` to enable a particular component to present itself using the visual language of the chosen design system. The FAST team ships two design systems: `fast-components`, which provide our team's own FAST Design system, and `@fluentui/web-components`, located in the [Fluent UI repo](https://github.com/microsoft/fluentui/), which provides Microsoft's Fluent Design system. If you want to build an app or site with Fluent Design, and you want to use web components as a technology solution, you can use `@fluentui/web-components` to meet that need today. - -### Who is behind FAST? - -The Microsoft FAST team builds and maintains all the `@microsoft/fast-*` packages as well as the `@fluentui/web-components` package. We are a collection of UX Engineers and Designers who are passionate about solving real-world UX challenges using web standard technologies. You can find us on [GitHub](https://github.com/microsoft/fast). - -### How does `fast-element` compare to "Framework X"? - -At this time, `fast-element` has a focus that's a bit different from the typical front-end framework. Rather than focusing on being a "mega SPA framework", `fast-element` endeavors to enable the creation of web components. As a result, you can use `fast-element` or any component built on `fast-element` in tandem with your favorite front-end framework. - -### What are Web Components? - -"Web Components" is an umbrella term that refers to a collection of web standards focused on enabling the creation of custom HTML elements. Some of the standards that are under the umbrella include the ability to define new HTML tags, plug into a standard component lifecycle, encapsulate HTML rendering and CSS, parameterize CSS, skin components, and more. Each of these platform features is defined by the W3C and has shipped in every major browsers today. - -### Why does FAST have components that are already available in HTML? - -Various members of our community have wondered why FAST has components that seem to mirror native elements. Examples include `fast-anchor`, `fast-button`, and `fast-divider`. There are several reasons for this: - -- CSS Encapsulation - By using Shadow DOM, FAST is able to provide a set of styles for these elements and guarantee that they will not conflict with your site or app. Your site styles will not break FAST and FAST will not break your site. -- CSS Behaviors - Custom elements enable FAST to dynamically add/remove styles based on runtime conditions, such as toggling high contrast mode. They also enable components to hook into the _design system_ and respond to design changes over time. -- Enhanced Anatomies - The FAST team refers to the DOM structure of a component as its "anatomy". This is an important detail of [a component spec](https://github.com/microsoft/fast/tree/master/specs). Our research as part of [OpenUI](https://open-ui.org/) has revealed common anatomies across many design systems and component libraries that are not reflected by a single standard HTML element. We leverage this research to design the structure of our FAST components so that they are built in a way that meets real-world needs, particularly regarding composition with other components. Some basic components, such as `anchor`, benefit from an expanded anatomy, based on industry usage. Through custom elements, we are able to implement this anatomy without inflicting an HTML authoring burden on our community. diff --git a/packages/web-components/src/_docs/resources/license.stories.mdx b/packages/web-components/src/_docs/resources/license.stories.mdx deleted file mode 100644 index 85a8fcdf4a90b..0000000000000 --- a/packages/web-components/src/_docs/resources/license.stories.mdx +++ /dev/null @@ -1,27 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -## License - -### MIT License - -Copyright (c) Microsoft Corporation. All rights reserved. - -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 diff --git a/packages/web-components/src/_docs/resources/security.stories.mdx b/packages/web-components/src/_docs/resources/security.stories.mdx deleted file mode 100644 index 1574ed33e4f06..0000000000000 --- a/packages/web-components/src/_docs/resources/security.stories.mdx +++ /dev/null @@ -1,45 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - - - -## Security - -Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). - -If you believe you have found a security vulnerability in any Microsoft-owned repository that meets Microsoft's [Microsoft's definition of a security vulnerability](), please report it to us as described below. - -## Reporting Security Issues - -**Please do not report security vulnerabilities through public GitHub issues.** - -Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). - -If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). - -You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). - -Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: - -- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) -- Full paths of source file(s) related to the manifestation of the issue -- The location of the affected source code (tag/branch/commit or direct URL) -- Any special configuration required to reproduce the issue -- Step-by-step instructions to reproduce the issue -- Proof-of-concept or exploit code (if possible) -- Impact of the issue, including how an attacker might exploit the issue - -This information will help us triage your report more quickly. - -If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. - -## Preferred Languages - -We prefer all communications to be in English. - -## Policy - -Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). - - diff --git a/packages/web-components/src/accordion/accordion-item/accordion-item.styles.ts b/packages/web-components/src/accordion/accordion-item/accordion-item.styles.ts deleted file mode 100644 index 718f4f8d1201d..0000000000000 --- a/packages/web-components/src/accordion/accordion-item/accordion-item.styles.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - AccordionItemOptions, - DesignToken, - display, - ElementDefinitionContext, - focusVisible, - forcedColorsStylesheetBehavior, -} from '@microsoft/fast-foundation'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { Swatch } from '../../color/swatch'; -import { - controlCornerRadius, - designUnit, - layerCornerRadius, - neutralFillLayerAltRest, - neutralFillLayerRecipe, - neutralFillLayerRest, - neutralFillStealthRecipe, - neutralForegroundRest, - neutralStrokeLayerRest, - strokeWidth, -} from '../../design-tokens'; -import { focusTreatmentBase } from '../../styles/focus'; -import { typeRampBase } from '../../styles/patterns/type-ramp'; -import { heightNumber } from '../../styles/size'; - -const neutralFillStealthRestOnNeutralFillLayerRest = DesignToken.create( - 'neutral-fill-stealth-rest-on-neutral-fill-layer-rest', -).withDefault((target: HTMLElement) => { - const baseRecipe = neutralFillLayerRecipe.getValueFor(target); - const buttonRecipe = neutralFillStealthRecipe.getValueFor(target); - return buttonRecipe.evaluate(target, baseRecipe.evaluate(target).rest).rest; -}); - -const neutralFillStealthHoverOnNeutralFillLayerRest = DesignToken.create( - 'neutral-fill-stealth-hover-on-neutral-fill-layer-rest', -).withDefault((target: HTMLElement) => { - const baseRecipe = neutralFillLayerRecipe.getValueFor(target); - const buttonRecipe = neutralFillStealthRecipe.getValueFor(target); - return buttonRecipe.evaluate(target, baseRecipe.evaluate(target).rest).hover; -}); - -const neutralFillStealthActiveOnNeutralFillLayerRest = DesignToken.create( - 'neutral-fill-stealth-active-on-neutral-fill-layer-rest', -).withDefault((target: HTMLElement) => { - const baseRecipe = neutralFillLayerRecipe.getValueFor(target); - const buttonRecipe = neutralFillStealthRecipe.getValueFor(target); - return buttonRecipe.evaluate(target, baseRecipe.evaluate(target).rest).active; -}); - -export const accordionItemStyles: ( - context: ElementDefinitionContext, - definition: AccordionItemOptions, -) => ElementStyles = (context: ElementDefinitionContext, definition: AccordionItemOptions) => - css` - ${display('flex')} :host { - box-sizing: border-box; - ${typeRampBase}; - flex-direction: column; - background: ${neutralFillLayerRest}; - color: ${neutralForegroundRest}; - border: calc(${strokeWidth} * 1px) solid ${neutralStrokeLayerRest}; - border-radius: calc(${layerCornerRadius} * 1px); - } - - .region { - display: none; - padding: calc(${designUnit} * 2 * 1px); - background: ${neutralFillLayerAltRest}; - } - - .heading { - display: grid; - position: relative; - grid-template-columns: auto 1fr auto auto; - align-items: center; - } - - .button { - appearance: none; - border: none; - background: none; - grid-column: 2; - grid-row: 1; - outline: none; - margin: calc(${designUnit} * 3 * 1px) 0; - padding: 0 calc(${designUnit} * 2 * 1px); - text-align: left; - color: inherit; - cursor: pointer; - font: inherit; - } - - .button::before { - content: ''; - position: absolute; - top: calc(${strokeWidth} * -1px); - left: calc(${strokeWidth} * -1px); - right: calc(${strokeWidth} * -1px); - bottom: calc(${strokeWidth} * -1px); - cursor: pointer; - } - - .button:${focusVisible}::before { - ${focusTreatmentBase} - border-radius: calc(${layerCornerRadius} * 1px); - } - - :host(.expanded) .button:${focusVisible}::before { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - } - - :host(.expanded) .region { - display: block; - border-top: calc(${strokeWidth} * 1px) solid ${neutralStrokeLayerRest}; - border-bottom-left-radius: calc((${layerCornerRadius} - ${strokeWidth}) * 1px); - border-bottom-right-radius: calc((${layerCornerRadius} - ${strokeWidth}) * 1px); - } - - .icon { - display: flex; - align-items: center; - justify-content: center; - grid-column: 4; - pointer-events: none; - background: ${neutralFillStealthRestOnNeutralFillLayerRest}; - border-radius: calc(${controlCornerRadius} * 1px); - fill: currentcolor; - width: calc(${heightNumber} * 1px); - height: calc(${heightNumber} * 1px); - margin: calc(${designUnit} * 2 * 1px); - } - - .heading:hover .icon { - background: ${neutralFillStealthHoverOnNeutralFillLayerRest}; - } - - .heading:active .icon { - background: ${neutralFillStealthActiveOnNeutralFillLayerRest}; - } - - slot[name='collapsed-icon'] { - display: flex; - } - - :host(.expanded) slot[name='collapsed-icon'] { - display: none; - } - - slot[name='expanded-icon'] { - display: none; - } - - :host(.expanded) slot[name='expanded-icon'] { - display: flex; - } - - .start { - display: flex; - align-items: center; - padding-inline-start: calc(${designUnit} * 2 * 1px); - justify-content: center; - grid-column: 1; - } - - .end { - display: flex; - align-items: center; - justify-content: center; - grid-column: 3; - } - - .icon, - .start, - .end { - position: relative; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - .button:${focusVisible}::before { - outline-color: ${SystemColors.Highlight}; - } - .icon { - fill: ${SystemColors.ButtonText}; - } - `, - ), - ); diff --git a/packages/web-components/src/accordion/accordion-item/accordion-item.vscode.definition.json b/packages/web-components/src/accordion/accordion-item/accordion-item.vscode.definition.json deleted file mode 100644 index 61b7b1f4d9325..0000000000000 --- a/packages/web-components/src/accordion/accordion-item/accordion-item.vscode.definition.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-accordion-item", - "title": "Accordion item", - "description": "The Fluent UI accordion item element", - "attributes": [ - { - "name": "heading-level", - "title": "Level", - "description": "The aria-level value (1-6) for the item heading, representing its semantic hierarchy", - "type": "number", - "default": 2, - "required": false - }, - { - "name": "expanded", - "title": "Expanded", - "description": "The expanded state of the item", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "id", - "title": "ID", - "description": "The HTML ID attribute for the invoking element", - "type": "string", - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The contents of the item" - }, - { - "name": "heading", - "title": "Heading slot", - "description": "The heading of the accordion item" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned before the heading" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the heading and before the expand/collapse icons" - }, - { - "name": "expanded-icon", - "title": "Expanded icon slot", - "description": "Slot to provide a custom icon representing the expanded state" - }, - { - "name": "collapsed-icon", - "title": "Collapsed icon slot", - "description": "Slot to provide a custom icon representing the collapsed state" - } - ] - } - ] -} diff --git a/packages/web-components/src/accordion/accordion-item/index.ts b/packages/web-components/src/accordion/accordion-item/index.ts deleted file mode 100644 index 366862f341fb1..0000000000000 --- a/packages/web-components/src/accordion/accordion-item/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { AccordionItem, AccordionItemOptions, accordionItemTemplate as template } from '@microsoft/fast-foundation'; -import { accordionItemStyles as styles } from './accordion-item.styles'; - -/** - * The Fluent Accordion Item Element. Implements {@link @microsoft/fast-foundation#AccordionItem}, - * {@link @microsoft/fast-foundation#accordionItemTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentAccordionItem = AccordionItem.compose({ - baseName: 'accordion-item', - template, - styles, - collapsedIcon: ` - - - - `, - expandedIcon: ` - - - - `, -}); - -/** - * Styles for AccordionItem - * @public - */ -export const accordionItemStyles = styles; - -export { AccordionItem }; diff --git a/packages/web-components/src/accordion/accordion.stories.ts b/packages/web-components/src/accordion/accordion.stories.ts deleted file mode 100644 index 178fa64fd9c35..0000000000000 --- a/packages/web-components/src/accordion/accordion.stories.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { fluentAccordion } from './index'; - -export default { - title: 'Components/Accordion', - component: fluentAccordion, - argTypes: { - expandMode: { - options: ['single', 'multi'], - control: { type: 'radio' }, - defaultValue: 'multi', - }, - }, -}; - -const AccordionTemplate = ({ expandMode }) => ` - - -
- -
-
- -
- Panel one - Panel one content -
- - Panel two - Panel two content - - - Panel three - Panel three content - -
-`; - -export const Accordion = AccordionTemplate.bind({}); - -const example = ` - - -
- -
-
- -
- Panel one - Panel one content -
- - Panel two - Panel two content - - - Panel three - Panel three content - -
-`; - -Accordion.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/accordion/accordion.styles.ts b/packages/web-components/src/accordion/accordion.styles.ts deleted file mode 100644 index 736479803c3d8..0000000000000 --- a/packages/web-components/src/accordion/accordion.styles.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { display, ElementDefinitionContext, FoundationElementDefinition } from '@microsoft/fast-foundation'; -import { designUnit, neutralForegroundRest } from '../design-tokens'; -import { typeRampBase } from '../styles/patterns/type-ramp'; - -export const accordionStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - ${display('flex')} :host { - box-sizing: border-box; - flex-direction: column; - ${typeRampBase} - color: ${neutralForegroundRest}; - gap: calc(${designUnit} * 1px); - } - `; diff --git a/packages/web-components/src/accordion/accordion.vscode.definition.json b/packages/web-components/src/accordion/accordion.vscode.definition.json deleted file mode 100644 index 6bc434fdf64d2..0000000000000 --- a/packages/web-components/src/accordion/accordion.vscode.definition.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-accordion", - "title": "Accordion", - "description": "The Fluent UI accordion element", - "attributes": [ - { - "name": "expand-mode", - "title": "Expand mode", - "description": "The way items are allowed to expand", - "type": "string", - "values": [ - { - "name": "single" - }, - { - "name": "multi" - } - ], - "default": "multi", - "required": false - } - ], - "slots": [ - { - "name": "item", - "title": "Item slot", - "description": "The default slot for accordion items" - } - ] - } - ] -} diff --git a/packages/web-components/src/accordion/fixtures/base.html b/packages/web-components/src/accordion/fixtures/base.html deleted file mode 100644 index 50f6d6f8839de..0000000000000 --- a/packages/web-components/src/accordion/fixtures/base.html +++ /dev/null @@ -1,46 +0,0 @@ -

Accordion

-

Default

- - -
- -
-
- -
- - Panel one - Some detail info - - Panel one content -
- - Panel two - Panel two content - - - Panel three - Panel three content - -
-

Single expand

- - -
- -
-
- -
- Panel one - Panel one content -
- - Panel Two - Panel two content - - - Panel three - Panel three content - -
diff --git a/packages/web-components/src/accordion/index.ts b/packages/web-components/src/accordion/index.ts deleted file mode 100644 index 5a20490172bb7..0000000000000 --- a/packages/web-components/src/accordion/index.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Accordion, accordionTemplate as template } from '@microsoft/fast-foundation'; -import { accordionStyles as styles } from './accordion.styles'; - -export * from './accordion-item/index'; - -/** - * The Fluent Accordion Element. Implements {@link @microsoft/fast-foundation#Accordion}, - * {@link @microsoft/fast-foundation#accordionTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentAccordion = Accordion.compose({ - baseName: 'accordion', - template, - styles, -}); - -/** - * Styles for Accordion - * @public - */ -export const accordionStyles = styles; - -/** - * Base class for Accordion - * @public - */ -export { Accordion }; diff --git a/packages/web-components/src/anchor/anchor.stories.ts b/packages/web-components/src/anchor/anchor.stories.ts deleted file mode 100644 index 545da4de6ca3e..0000000000000 --- a/packages/web-components/src/anchor/anchor.stories.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { fluentAnchor } from './index'; - -export default { - title: 'Components/Anchor', - component: fluentAnchor, - argTypes: { - appearance: { - options: ['neutral', 'accent', 'hypertext', 'lightweight', 'outline', 'stealth'], - control: { type: 'radio' }, - }, - }, -}; - -const AnchorTemplate = ({ appearance, label }) => ` - - ${label} - -`; - -export const Anchor = AnchorTemplate.bind({}); - -const example = ` -Anchor -`; - -Anchor.args = { - label: 'Anchor', - appearance: 'neutral', -}; - -Anchor.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/anchor/anchor.styles.ts b/packages/web-components/src/anchor/anchor.styles.ts deleted file mode 100644 index d076bfda6ad5a..0000000000000 --- a/packages/web-components/src/anchor/anchor.styles.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ElementStyles } from '@microsoft/fast-element'; -import { ElementDefinitionContext, FoundationElementDefinition } from '@microsoft/fast-foundation'; -import { - AccentButtonStyles, - baseButtonStyles, - HypertextStyles, - LightweightButtonStyles, - NeutralButtonStyles, - OutlineButtonStyles, - StealthButtonStyles, -} from '../styles/'; -import { appearanceBehavior } from '../utilities/behaviors'; - -const interactivitySelector: string = '[href]'; - -export const anchorStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - baseButtonStyles(context, definition, interactivitySelector) - .withBehaviors( - appearanceBehavior('neutral', NeutralButtonStyles(context, definition, interactivitySelector)), - appearanceBehavior('accent', AccentButtonStyles(context, definition, interactivitySelector)), - appearanceBehavior('hypertext', HypertextStyles(context, definition, interactivitySelector)), - appearanceBehavior('lightweight', LightweightButtonStyles(context, definition, interactivitySelector)), - appearanceBehavior('outline', OutlineButtonStyles(context, definition, interactivitySelector)), - appearanceBehavior('stealth', StealthButtonStyles(context, definition, interactivitySelector)), - ); diff --git a/packages/web-components/src/anchor/anchor.vscode.definition.json b/packages/web-components/src/anchor/anchor.vscode.definition.json deleted file mode 100644 index a760b306df1fd..0000000000000 --- a/packages/web-components/src/anchor/anchor.vscode.definition.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-anchor", - "title": "Anchor", - "description": "The Fluent UI anchor element", - "attributes": [ - { - "name": "appearance", - "title": "Appearance", - "description": "The anchor's visual treatment", - "type": "string", - "values": [ - { - "name": "accent" - }, - { - "name": "lightweight" - }, - { - "name": "neutral" - }, - { - "name": "outline" - }, - { - "name": "stealth" - }, - { - "name": "hypertext" - } - ], - "default": "neutral", - "required": false - }, - { - "name": "download", - "title": "Download", - "description": "The HTML download attribute of the anchor", - "type": "string", - "required": false - }, - { - "name": "href", - "title": "URL", - "description": "The URL the anchor points to", - "type": "string", - "required": false - }, - { - "name": "hreflang", - "title": "Linked page language", - "description": "The language of the URL the anchor points to", - "type": "string", - "required": false - }, - { - "name": "ping", - "title": "Ping URLs", - "description": "A space-separated list of URLs typically for tracking", - "type": "string", - "required": false - }, - { - "name": "referrerpolicy", - "title": "Referrer policy", - "description": "The amount of referrer information that should be included with requests", - "type": "string", - "required": false, - "values": [ - { "name": "no-referrer" }, - { "name": "no-referrer-when-downgrade" }, - { "name": "origin" }, - { "name": "origin-when-cross-origin" }, - { "name": "same-origin" }, - { "name": "strict-origin" }, - { "name": "strict-origin-when-cross-origin" }, - { "name": "unsafe-url" } - ] - }, - { - "name": "rel", - "title": "Relationship", - "description": "Space-separated link types indicating the relationship of the linked URL", - "type": "string", - "required": false - }, - { - "name": "target", - "title": "Target", - "description": "The display target of the URL", - "type": "string", - "default": "_self", - "values": [ - { - "name": "_self" - }, - { - "name": "_blank" - }, - { - "name": "_parent" - }, - { - "name": "_top" - } - ], - "required": false - }, - { - "name": "type", - "title": "Type", - "description": "The linked URL's format using a MIME type", - "type": "string", - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the anchor" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned before the anchor content" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the anchor content" - } - ] - } - ] -} diff --git a/packages/web-components/src/anchor/fixtures/anchor.html b/packages/web-components/src/anchor/fixtures/anchor.html deleted file mode 100644 index 0990fa38ff913..0000000000000 --- a/packages/web-components/src/anchor/fixtures/anchor.html +++ /dev/null @@ -1,131 +0,0 @@ - - -

Anchor

-

with href / without href

- -

Default

-
- Anchor - Anchor -
- -

With target

-
- Anchor - Anchor -
- -

Neutral

-
- Anchor - Anchor -
- -

Accent

-
- Anchor - Anchor -
- -

Hypertext

-
- Anchor - Anchor -
- -

Inline

-

- Lorem ipsum dolor sit amet (no href) consectetur adipisicing - elit. Nesciunt ut aliquam quas quod ipsam cupiditate, voluptate, corrupti - doloremque totam - dicta perspiciatis commodi consequatur reprehenderit laborum aliquid minima. Neque, recusandae. Adipisci. -

- -

Lightweight

-
- Anchor - Anchor -
- -

Outline

-
- Anchor - Anchor -
- -

Stealth

-
- Anchor - Anchor -
- -

With start

-
- - Anchor - - - - - - Anchor - - - - -
- -

With end

-
- - Anchor - - - - - - Anchor - - - - -
- -

Icon in default slot

-
- - - - - - - - - - -
- -

With aria-label

-
- - -
diff --git a/packages/web-components/src/anchor/index.ts b/packages/web-components/src/anchor/index.ts deleted file mode 100644 index ae1048b3a4f6c..0000000000000 --- a/packages/web-components/src/anchor/index.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { attr } from '@microsoft/fast-element'; -import { Anchor as FoundationAnchor, anchorTemplate as template } from '@microsoft/fast-foundation'; -import { ButtonAppearance } from '../button'; -import { anchorStyles as styles } from './anchor.styles'; - -/** - * Types of anchor appearance. - * @public - */ -export type AnchorAppearance = ButtonAppearance | 'hypertext'; - -/** - * The Fluent version of Anchor - * @internal - */ -export class Anchor extends FoundationAnchor { - /** - * The appearance the anchor should have. - * - * @public - * @remarks - * HTML Attribute: appearance - */ - @attr - public appearance?: AnchorAppearance; - public appearanceChanged(oldValue: AnchorAppearance, newValue: AnchorAppearance): void { - if (oldValue !== newValue) { - this.classList.add(newValue); - this.classList.remove(oldValue); - } - } - - /** - * @internal - */ - public connectedCallback(): void { - super.connectedCallback(); - - if (!this.appearance) { - this.appearance = 'neutral'; - } - } - - /** - * Applies 'icon-only' class when there is only an SVG in the default slot - * - * @internal - */ - public defaultSlottedContentChanged(): void { - const slottedElements = this.defaultSlottedContent.filter(x => x.nodeType === Node.ELEMENT_NODE); - - if (slottedElements.length === 1 && slottedElements[0] instanceof SVGElement) { - this.control?.classList.add('icon-only'); - } else { - this.control?.classList.remove('icon-only'); - } - } -} - -/** - * Styles for Anchor - * @public - */ -export const anchorStyles = styles; - -/** - * The Fluent Anchor Element. Implements {@link @microsoft/fast-foundation#Anchor}, - * {@link @microsoft/fast-foundation#anchorTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - * - * {@link https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus | delegatesFocus} - */ -export const fluentAnchor = Anchor.compose({ - baseName: 'anchor', - baseClass: FoundationAnchor, - template, - styles, - shadowOptions: { - delegatesFocus: true, - }, -}); diff --git a/packages/web-components/src/anchored-region/anchored-region.stories.ts b/packages/web-components/src/anchored-region/anchored-region.stories.ts deleted file mode 100644 index d821014410612..0000000000000 --- a/packages/web-components/src/anchored-region/anchored-region.stories.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { DOCS_RENDERED } from '@storybook/core-events'; -import addons from '@storybook/addons'; -import { Direction, RtlScrollConverter } from '@microsoft/fast-web-utilities'; -import { AnchoredRegion } from '@microsoft/fast-foundation'; -import AnchoreRegionTemplate from './fixtures/base.html'; -import './index'; - -let scalingViewportPreviousXValue: number = 250; -let scalingViewportPreviousYValue: number = 250; - -addons.getChannel().addListener(DOCS_RENDERED, (name: string) => { - if (name.toLowerCase().includes('anchored region')) { - scrollViewports(); - setButtonActions(); - - const scalingViewportUpdate: HTMLElement | null = document.getElementById('viewport-scaling-update'); - if (scalingViewportUpdate !== null) { - scalingViewportUpdate.addEventListener('scroll', handleScrollViaUpdate); - } - - const scalingViewportOffset: HTMLElement | null = document.getElementById('viewport-scaling-offset'); - if (scalingViewportOffset !== null) { - scalingViewportOffset.addEventListener('scroll', handleScrollViaOffset); - } - } -}); - -function scrollViewports(): void { - document.querySelectorAll("div[id^='viewport']").forEach(el => { - if (el instanceof HTMLDivElement) { - el.scrollTop = 280; - RtlScrollConverter.setScrollLeft( - el, - el.dir === Direction.rtl ? -250 : 250, - el.dir === Direction.rtl ? Direction.rtl : Direction.ltr, - ); - } - }); -} - -function handleScrollViaUpdate(ev: Event): void { - if (ev.target instanceof HTMLElement) { - const scalingRegionUpdate: HTMLElement | null = document.getElementById('region-scaling-update'); - if (scalingRegionUpdate instanceof AnchoredRegion) { - (scalingRegionUpdate as any).update(); - } - } -} - -function handleScrollViaOffset(ev: Event): void { - if (ev.target instanceof HTMLElement) { - const scroller: HTMLElement = ev.target as HTMLElement; - - const scalingRegionOffset: HTMLElement | null = document.getElementById('region-scaling-offset'); - if (scalingRegionOffset instanceof AnchoredRegion) { - (scalingRegionOffset as any).updateAnchorOffset( - scalingViewportPreviousXValue - scroller.scrollLeft, - scalingViewportPreviousYValue - scroller.scrollTop, - ); - } - - scalingViewportPreviousXValue = scroller.scrollLeft; - scalingViewportPreviousYValue = scroller.scrollTop; - } -} - -function setButtonActions(): void { - document.querySelectorAll('button').forEach(el => { - if (el instanceof HTMLButtonElement) { - switch (el.id) { - case 'toggle-anchor-anchor1': - el.onclick = event => { - const region: HTMLElement | null = document.getElementById('toggle-anchor-region'); - if (region === null) { - return; - } - region.setAttribute('anchor', 'toggle-anchor-anchor1'); - }; - break; - - case 'toggle-anchor-anchor2': - el.onclick = event => { - const region: HTMLElement | null = document.getElementById('toggle-anchor-region'); - if (region === null) { - return; - } - region.setAttribute('anchor', 'toggle-anchor-anchor2'); - }; - break; - - case 'toggle-positions-horizontal': - el.onclick = event => { - const region: HTMLElement | null = document.getElementById('toggle-positions-region'); - if (region === null) { - return; - } - const currentPosition: string | null = region.getAttribute('horizontal-default-position'); - if (currentPosition === 'left') { - region.setAttribute('horizontal-default-position', 'right'); - } else { - region.setAttribute('horizontal-default-position', 'left'); - } - }; - break; - - case 'toggle-positions-vertical': - el.onclick = event => { - const region: HTMLElement | null = document.getElementById('toggle-positions-region'); - if (region === null) { - return; - } - const currentPosition: string | null = region.getAttribute('vertical-default-position'); - if (currentPosition === 'top') { - region.setAttribute('vertical-default-position', 'bottom'); - } else { - region.setAttribute('vertical-default-position', 'top'); - } - }; - break; - - case 'toggle-positions-small': - el.onclick = event => { - const smallContent: HTMLElement | null = document.getElementById('toggle-positions-small'); - const largeContent: HTMLElement | null = document.getElementById('toggle-positions-large'); - if (smallContent === null || largeContent === null) { - return; - } - - smallContent.hidden = false; - largeContent.hidden = true; - }; - break; - - case 'toggle-positions-large': - el.onclick = event => { - const smallContent: HTMLElement | null = document.getElementById('toggle-positions-small'); - const largeContent: HTMLElement | null = document.getElementById('toggle-positions-large'); - if (smallContent === null || largeContent === null) { - return; - } - - smallContent.hidden = true; - largeContent.hidden = false; - }; - break; - - default: - el.onclick; - } - } - }); -} - -export default { - title: 'Components/Anchored region', -}; - -export const base = () => AnchoreRegionTemplate; diff --git a/packages/web-components/src/anchored-region/anchored-region.styles.ts b/packages/web-components/src/anchored-region/anchored-region.styles.ts deleted file mode 100644 index 322a38421f263..0000000000000 --- a/packages/web-components/src/anchored-region/anchored-region.styles.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { ElementDefinitionContext, FoundationElementDefinition } from '@microsoft/fast-foundation'; - -export const anchoredRegionStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => css` - :host { - contain: layout; - display: block; - } -`; diff --git a/packages/web-components/src/anchored-region/anchored-region.vscode.definition.json b/packages/web-components/src/anchored-region/anchored-region.vscode.definition.json deleted file mode 100644 index 18bc3540bbfe3..0000000000000 --- a/packages/web-components/src/anchored-region/anchored-region.vscode.definition.json +++ /dev/null @@ -1,140 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-anchored-region", - "title": "Anchored region", - "description": "The Fluent UI anchored region element", - "attributes": [ - { - "name": "anchor", - "title": "Anchor ID", - "type": "string", - "description": "The HTML ID of the element the region is positioned relative to", - "required": true - }, - { - "name": "viewport", - "title": "Viewport ID", - "description": "The HTML ID of the viewport the region is positioned relative to", - "type": "string", - "required": false - }, - { - "name": "horizontal-positioning-mode", - "title": "Horizontal positioning mode", - "description": "How the horizontal placement is determined", - "type": "string", - "values": [{ "name": "uncontrolled" }, { "name": "locktodefault" }, { "name": "dynamic" }], - "default": "uncontrolled", - "required": false - }, - { - "name": "horizontal-default-position", - "title": "Horizontal default position", - "description": "The default horizontal position of the region relative to the configured 'Anchor ID'", - "type": "string", - "values": [ - { "name": "start" }, - { "name": "end" }, - { "name": "left" }, - { "name": "right" }, - { "name": "unset" } - ], - "default": "unset", - "required": false - }, - { - "name": "horizontal-inset", - "title": "Horizontal inset", - "description": "Determines whether the region should overlap the anchor on the horizontal axis", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "horizontal-threshold", - "title": "Horizontal threshold", - "description": "The space allocated to the default position before the widest area is selected for layout", - "type": "number", - "required": false - }, - { - "name": "horizontal-scaling", - "title": "Horizontal scaling", - "description": "Defines how the width of the region is calculated", - "type": "string", - "values": [{ "name": "anchor" }, { "name": "fill" }, { "name": "content" }], - "default": "content", - "required": false - }, - { - "name": "vertical-positioning-mode", - "title": "Vertical positioning mode", - "description": "How the vertical placement is determined", - "type": "string", - "values": [{ "name": "uncontrolled" }, { "name": "locktodefault" }, { "name": "dynamic" }], - "default": "uncontrolled", - "required": false - }, - { - "name": "vertical-default-position", - "title": "Vertical default position", - "description": "The default vertical position of the region relative to the configured 'Anchor ID'", - "type": "string", - "values": [{ "name": "top" }, { "name": "bottom" }, { "name": "unset" }], - "default": "unset", - "required": false - }, - { - "name": "vertical-inset", - "title": "Vertical inset", - "description": "Determines whether the region should overlap the anchor on the vertical axis", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "vertical-threshold", - "title": "Vertical threshold", - "description": "The space allocated to the default position before the widest area is selected for layout", - "type": "number", - "required": false - }, - { - "name": "vertical-scaling", - "title": "Vertical scaling", - "description": "Defines how the width of the region is calculated", - "type": "string", - "values": [{ "name": "anchor" }, { "name": "fill" }, { "name": "content" }], - "default": "content", - "required": false - }, - { - "name": "fixed-placement", - "title": "Fixed placement", - "description": "Fixed placement allows the region to break out of parent containers", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "auto-update-mode", - "title": "Auto update mode", - "description": "Defines whether the component automatically updates its position", - "type": "string", - "values": [{ "name": "anchor" }, { "name": "auto" }], - "default": "anchor", - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the anchored region" - } - ] - } - ] -} diff --git a/packages/web-components/src/anchored-region/fixtures/anchored-region.html b/packages/web-components/src/anchored-region/fixtures/anchored-region.html deleted file mode 100644 index f728621585a26..0000000000000 --- a/packages/web-components/src/anchored-region/fixtures/anchored-region.html +++ /dev/null @@ -1,368 +0,0 @@ -
- -
outside
-
- -
-

Anchored region

- - -
inside
-
-
- -
-

Dynamic - default

-
-
- - -
-
-
-
- -

Lock to default

-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
- -

Scaling via update

-
-
- - -
-
-
-
- -

Scaling via offset

-
-
- - -
-
-
-
- -

Inset

-
-
- - -
-
-
-
- -

Thresholds

-
-
- - -
-
-
-
- -

Toggle anchor

-
-
- - - -
-
-
-
- -

Toggle positions and size

-
-
- - - -
-
-
- - - - -
-
-
- -

RTL-dynamic

-
-
- -
-
- -
-
- -

Size to anchor

-
-
- -
-
- -
-
- -

RTL-fill

-
-
- - -
-
-
-
- -

Start & End

-
-
- - -
-
- - -
-
-
-
- -

RTL-Start & End

-
-
- - -
-
- - -
-
-
-
-
- -
outside & fixed
-
-
diff --git a/packages/web-components/src/anchored-region/fixtures/base.html b/packages/web-components/src/anchored-region/fixtures/base.html deleted file mode 100644 index 38bd957cd1d22..0000000000000 --- a/packages/web-components/src/anchored-region/fixtures/base.html +++ /dev/null @@ -1,389 +0,0 @@ - -
- -
outside
-
- -
-

Anchored region

- - -
inside
-
-
- -
-

Dynamic - default

-
-
- - anchor - -
-
-
-
- -

Lock to default

-
-
- -
-
-
- -
-
-
- -
-
-
- anchor - -
-
- -

Scaling via update

-
-
- - anchor - -
-
-
-
- -

Scaling via offset

-
-
- - anchor - -
-
-
-
- -

Inset

-
-
- anchor - - -
-
-
-
- -

Thresholds

-
-
- anchor - - -
-
-
-
- -

Toggle anchor

-
-
- - - -
-
-
-
- -

Toggle positions and size

-
-
- - anchor - - -
-
-
- - - - -
-
-
- -

RTL-dynamic

-
-
- -
-
- - anchor -
-
- -

Size to anchor

-
-
- -
-
- -
-
- -

RTL-fill

-
-
- - -
-
-
-
- -

Start & End

-
-
- - -
-
- - -
-
-
-
- -

RTL-Start & End

-
-
- - -
-
- - -
-
-
-
-
- -
outside & fixed
-
-
diff --git a/packages/web-components/src/anchored-region/index.ts b/packages/web-components/src/anchored-region/index.ts deleted file mode 100644 index 957d68885fe2d..0000000000000 --- a/packages/web-components/src/anchored-region/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { AnchoredRegion, anchoredRegionTemplate as template } from '@microsoft/fast-foundation'; -import { anchoredRegionStyles as styles } from './anchored-region.styles'; - -/** - * The Fluent AnchoredRegion Element. Implements {@link @microsoft/fast-foundation#AnchoredRegion}, - * {@link @microsoft/fast-foundation#anchoredRegionTemplate} - * - * - * @beta - * @remarks - * HTML Element: \ - */ -export const fluentAnchoredRegion = AnchoredRegion.compose({ - baseName: 'anchored-region', - template, - styles, -}); - -/** - * Styles for AnchoredRegion - * @public - */ -export const anchoredRegionStyles = styles; - -/** - * Base class for AnchoredRegion - * @public - */ -export { AnchoredRegion }; diff --git a/packages/web-components/src/badge/badge.stories.ts b/packages/web-components/src/badge/badge.stories.ts deleted file mode 100644 index 118604aa8cfca..0000000000000 --- a/packages/web-components/src/badge/badge.stories.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { fluentBadge } from './index'; - -export default { - title: 'Components/Badge', - component: fluentBadge, - argTypes: { - appearance: { - options: ['neutral', 'accent', 'lightweight'], - control: { type: 'radio' }, - }, - }, -}; - -const BadgeTemplate = ({ appearance, label }) => ` - ${label}`; - -export const Badge = BadgeTemplate.bind({}); - -Badge.args = { - label: 'Badge', - appearance: 'accent', -}; - -Badge.parameters = { - docs: { - source: { - code: `Text`, - }, - }, -}; diff --git a/packages/web-components/src/badge/badge.styles.ts b/packages/web-components/src/badge/badge.styles.ts deleted file mode 100644 index b6473087545b5..0000000000000 --- a/packages/web-components/src/badge/badge.styles.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { display, ElementDefinitionContext, FoundationElementDefinition } from '@microsoft/fast-foundation'; -import { - accentFillRest, - controlCornerRadius, - designUnit, - foregroundOnAccentRest, - neutralFillSecondaryRest, - neutralForegroundRest, - strokeWidth, - typeRampMinus1LineHeight, -} from '../design-tokens'; -import { typeRampMinus1 } from '../styles/patterns/type-ramp'; - -export const badgeStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - ${display('inline-block')} :host { - box-sizing: border-box; - ${typeRampMinus1}; - } - - .control { - border-radius: calc(${controlCornerRadius} * 1px); - padding: calc(((${designUnit} * 0.5) - ${strokeWidth}) * 1px) calc((${designUnit} - ${strokeWidth}) * 1px); - border: calc(${strokeWidth} * 1px) solid transparent; - } - - :host(.lightweight) .control { - background: transparent; - color: ${neutralForegroundRest}; - font-weight: 600; - } - - :host(.accent) .control { - background: ${accentFillRest}; - color: ${foregroundOnAccentRest}; - } - - :host(.neutral) .control { - background: ${neutralFillSecondaryRest}; - color: ${neutralForegroundRest}; - } - - :host([circular]) .control { - border-radius: 100px; - min-width: calc(${typeRampMinus1LineHeight} - calc(${designUnit} * 1px)); - display: flex; - align-items: center; - justify-content: center; - } - `; diff --git a/packages/web-components/src/badge/badge.vscode.definition.json b/packages/web-components/src/badge/badge.vscode.definition.json deleted file mode 100644 index 16f3921691e99..0000000000000 --- a/packages/web-components/src/badge/badge.vscode.definition.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-badge", - "title": "Badge", - "description": "The Fluent UI badge element", - "attributes": [ - { - "name": "circular", - "title": "Circular", - "description": "Sets the visual appearance of the badge to circular", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "fill", - "title": "Fill", - "description": "Sets the background color to a CSS custom property of the attribute value - var(--badge-fill-[value])", - "type": "string", - "required": false - }, - { - "name": "color", - "title": "Color", - "description": "Sets the color to a CSS custom property of the attribute value - var(--badge-color-[value])", - "type": "string", - "required": false - }, - { - "name": "appearance", - "title": "Appearance", - "description": "The badge's visual treatment", - "type": "string", - "values": [ - { - "name": "accent" - }, - { - "name": "lightweight" - }, - { - "name": "neutral" - } - ], - "default": "lightweight", - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the badge" - } - ] - } - ] -} diff --git a/packages/web-components/src/badge/fixtures/badge.html b/packages/web-components/src/badge/fixtures/badge.html deleted file mode 100644 index 15087d6499158..0000000000000 --- a/packages/web-components/src/badge/fixtures/badge.html +++ /dev/null @@ -1,24 +0,0 @@ - -

Badge

-

Default

-Badge -

Lightweight

-Badge -

Accent

-Badge -

Neutral

-Badge -

With map

-Badge -Badge -

Circular

- 9 - 99 - 9999999 diff --git a/packages/web-components/src/badge/index.ts b/packages/web-components/src/badge/index.ts deleted file mode 100644 index 0bd1991be6e57..0000000000000 --- a/packages/web-components/src/badge/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { attr, DOM } from '@microsoft/fast-element'; -import { Badge as FoundationBadge, badgeTemplate as template } from '@microsoft/fast-foundation'; -import { badgeStyles as styles } from './badge.styles'; - -/** - * Badge appearance options. - * @public - */ -export type BadgeAppearance = 'accent' | 'lightweight' | 'neutral' | string; - -/** - * The Fluent Badge class - * @internal - */ -export class Badge extends FoundationBadge { - @attr({ mode: 'fromView' }) - public appearance: BadgeAppearance = 'lightweight'; - private appearanceChanged(oldValue: BadgeAppearance, newValue: BadgeAppearance): void { - if (oldValue !== newValue) { - DOM.queueUpdate(() => { - this.classList.add(newValue); - this.classList.remove(oldValue); - }); - } - } -} - -/** - * The Fluent Badge Element. Implements {@link @microsoft/fast-foundation#Badge}, - * {@link @microsoft/fast-foundation#badgeTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentBadge = Badge.compose({ - baseName: 'badge', - baseClass: FoundationBadge, - template, - styles, -}); - -/** - * Styles for Badge - * @public - */ -export const badgeStyles = styles; diff --git a/packages/web-components/src/breadcrumb-item/breadcrumb-item.stories.ts b/packages/web-components/src/breadcrumb-item/breadcrumb-item.stories.ts deleted file mode 100644 index 90c111c0f3267..0000000000000 --- a/packages/web-components/src/breadcrumb-item/breadcrumb-item.stories.ts +++ /dev/null @@ -1,20 +0,0 @@ -import BreadcrumbItemTemplate from './fixtures/breadcrumb-item.html'; -import './index'; - -export default { - title: 'Components/Breadcrumb Item', -}; - -export const BreadcrumbItem = (): string => BreadcrumbItemTemplate; - -const example = ` - Breadcrumb item -`; - -BreadcrumbItem.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/breadcrumb-item/breadcrumb-item.styles.ts b/packages/web-components/src/breadcrumb-item/breadcrumb-item.styles.ts deleted file mode 100644 index b08e47d4c5087..0000000000000 --- a/packages/web-components/src/breadcrumb-item/breadcrumb-item.styles.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - BreadcrumbItemOptions, - display, - ElementDefinitionContext, - focusVisible, - forcedColorsStylesheetBehavior, -} from '@microsoft/fast-foundation'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { - controlCornerRadius, - neutralForegroundActive, - neutralForegroundHover, - neutralForegroundRest, -} from '../design-tokens'; -import { typeRampBase } from '../styles/patterns/type-ramp'; -import { heightNumber } from '../styles/index'; -import { focusTreatmentTight } from '../styles/focus'; - -export const breadcrumbItemStyles: ( - context: ElementDefinitionContext, - definition: BreadcrumbItemOptions, -) => ElementStyles = (context: ElementDefinitionContext, definition: BreadcrumbItemOptions) => - css` - ${display('inline-flex')} :host { - background: transparent; - color: ${neutralForegroundRest}; - fill: currentcolor; - box-sizing: border-box; - ${typeRampBase}; - min-width: calc(${heightNumber} * 1px); - border-radius: calc(${controlCornerRadius} * 1px); - } - - .listitem { - display: flex; - align-items: center; - border-radius: inherit; - } - - .control { - position: relative; - align-items: center; - box-sizing: border-box; - color: inherit; - fill: inherit; - cursor: pointer; - display: flex; - outline: none; - text-decoration: none; - white-space: nowrap; - border-radius: inherit; - } - - .control:hover { - color: ${neutralForegroundHover}; - } - - .control:active { - color: ${neutralForegroundActive}; - } - - .control:${focusVisible} { - ${focusTreatmentTight} - } - - :host(:not([href])), - :host([aria-current]) .control { - color: ${neutralForegroundRest}; - fill: currentcolor; - cursor: default; - } - - .start { - display: flex; - margin-inline-end: 6px; - } - - .end { - display: flex; - margin-inline-start: 6px; - } - - .separator { - display: flex; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host(:not([href])), - .start, - .end, - .separator { - background: ${SystemColors.ButtonFace}; - color: ${SystemColors.ButtonText}; - fill: currentcolor; - } - .separator { - fill: ${SystemColors.ButtonText}; - } - :host([href]) { - forced-color-adjust: none; - background: ${SystemColors.ButtonFace}; - color: ${SystemColors.LinkText}; - } - :host([href]) .control:hover { - background: ${SystemColors.LinkText}; - color: ${SystemColors.HighlightText}; - fill: currentcolor; - } - .control:${focusVisible} { - outline-color: ${SystemColors.LinkText}; - } - `, - ), - ); diff --git a/packages/web-components/src/breadcrumb-item/breadcrumb-item.vscode.definition.json b/packages/web-components/src/breadcrumb-item/breadcrumb-item.vscode.definition.json deleted file mode 100644 index 87f06a7ad60ad..0000000000000 --- a/packages/web-components/src/breadcrumb-item/breadcrumb-item.vscode.definition.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-breadcrumb-item", - "title": "Breadcrumb item", - "description": "The Fluent UI breadcrumb item element", - "attributes": [ - { - "name": "href", - "title": "URL", - "description": "The URL the item points to", - "type": "string", - "default": "", - "required": false - }, - { - "name": "separator", - "title": "Separator", - "description": "Determines whether the visual separator should be rendered", - "type": "boolean", - "default": true, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the item" - }, - { - "name": "separator", - "title": "Separator slot", - "description": "Slot to provide a custom icon to represent the visual separator" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned before the default content" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the default content" - } - ] - } - ] -} diff --git a/packages/web-components/src/breadcrumb-item/fixtures/breadcrumb-item.html b/packages/web-components/src/breadcrumb-item/fixtures/breadcrumb-item.html deleted file mode 100644 index 1019022ff2dd3..0000000000000 --- a/packages/web-components/src/breadcrumb-item/fixtures/breadcrumb-item.html +++ /dev/null @@ -1,37 +0,0 @@ -

Breadcrumbs

- -

Default

-Breadcrumb item - -

No href

-Breadcrumb item - -

Default with custom separator

- - Breadcrumb item - - - - - -

With start

- - Breadcrumb item - - - - - -

With end

- - Breadcrumb item - - - - diff --git a/packages/web-components/src/breadcrumb-item/index.ts b/packages/web-components/src/breadcrumb-item/index.ts deleted file mode 100644 index 18c39ec17afca..0000000000000 --- a/packages/web-components/src/breadcrumb-item/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { BreadcrumbItem, BreadcrumbItemOptions, breadcrumbItemTemplate as template } from '@microsoft/fast-foundation'; -import { breadcrumbItemStyles as styles } from './breadcrumb-item.styles'; - -/** - * The Fluent BreadcrumbItem Element. Implements {@link @microsoft/fast-foundation#BreadcrumbItem}, - * {@link @microsoft/fast-foundation#breadcrumbItemTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentBreadcrumbItem = BreadcrumbItem.compose({ - baseName: 'breadcrumb-item', - template, - styles, - shadowOptions: { - delegatesFocus: true, - }, - separator: ` - - - - `, -}); - -/** - * Styles for BreadcrumbItem - * @public - */ -export const breadcrumbItemStyles = styles; - -/** - * Base class for BreadcrumbItem - * @public - */ -export { BreadcrumbItem }; diff --git a/packages/web-components/src/breadcrumb/breadcrumb.stories.ts b/packages/web-components/src/breadcrumb/breadcrumb.stories.ts deleted file mode 100644 index 79700563bbcbc..0000000000000 --- a/packages/web-components/src/breadcrumb/breadcrumb.stories.ts +++ /dev/null @@ -1,24 +0,0 @@ -import BreadcrumbTemplate from './fixtures/breadcrumb.html'; -import './index'; - -export default { - title: 'Components/Breadcrumb', -}; - -export const Breadcrumb = (): string => BreadcrumbTemplate; - -const example = ` - - Breadcrumb item 1 - Breadcrumb item 2 - Breadcrumb item 3 - -`; - -Breadcrumb.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/breadcrumb/breadcrumb.styles.ts b/packages/web-components/src/breadcrumb/breadcrumb.styles.ts deleted file mode 100644 index 443030ff5b986..0000000000000 --- a/packages/web-components/src/breadcrumb/breadcrumb.styles.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { display, ElementDefinitionContext, FoundationElementDefinition } from '@microsoft/fast-foundation'; -import { typeRampBase } from '../styles/patterns/type-ramp'; - -export const breadcrumbStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => css` - ${display('inline-block')} :host { - box-sizing: border-box; - ${typeRampBase}; - } - - .list { - display: flex; - } -`; diff --git a/packages/web-components/src/breadcrumb/breadcrumb.vscode.definition.json b/packages/web-components/src/breadcrumb/breadcrumb.vscode.definition.json deleted file mode 100644 index 803a31e0b3135..0000000000000 --- a/packages/web-components/src/breadcrumb/breadcrumb.vscode.definition.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-breadcrumb", - "title": "Breadcrumb", - "description": "The Fluent UI breadcrumb element", - "attributes": [], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the breadcrumb, typically composed of fluent-breadcrumb-items or anchors" - } - ] - } - ] -} diff --git a/packages/web-components/src/breadcrumb/fixtures/breadcrumb.html b/packages/web-components/src/breadcrumb/fixtures/breadcrumb.html deleted file mode 100644 index 7d771f56650f8..0000000000000 --- a/packages/web-components/src/breadcrumb/fixtures/breadcrumb.html +++ /dev/null @@ -1,97 +0,0 @@ - - -

Breadcrumb

-

Default

- - Breadcrumb item 1 - Breadcrumb item 2 - Breadcrumb item 3 - - -

Default with custom separator

- - - Breadcrumb item 1 - - - - - - Breadcrumb item 2 - - - - - Breadcrumb item 3 - - -

With start

- - - Breadcrumb item 1 - - - - - - Breadcrumb item 2 - - - - - - Breadcrumb item 3 - - - - - - -

With end

- - - Breadcrumb item 1 - - - - - - Breadcrumb item 2 - - - - - - Breadcrumb item 3 - - - - - - -

With aria-current

- - Breadcrumb item 1 - Breadcrumb item 2 - Breadcrumb item 3 - diff --git a/packages/web-components/src/breadcrumb/index.ts b/packages/web-components/src/breadcrumb/index.ts deleted file mode 100644 index 9f7d26c15ca58..0000000000000 --- a/packages/web-components/src/breadcrumb/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Breadcrumb, breadcrumbTemplate as template } from '@microsoft/fast-foundation'; -import { breadcrumbStyles as styles } from './breadcrumb.styles'; - -/** - * The Fluent Breadcrumb Element. Implements {@link @microsoft/fast-foundation#Breadcrumb}, - * {@link @microsoft/fast-foundation#breadcrumbTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentBreadcrumb = Breadcrumb.compose({ - baseName: 'breadcrumb', - template, - styles, -}); - -/** - * Styles for Breadcrumb - * @public - */ -export const breadcrumbStyles = styles; - -/** - * Base class for Breadcrumb - * @public - */ -export { Breadcrumb }; diff --git a/packages/web-components/src/button/button.stories.ts b/packages/web-components/src/button/button.stories.ts deleted file mode 100644 index db784778b0cb6..0000000000000 --- a/packages/web-components/src/button/button.stories.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { fluentButton } from './index'; - -export default { - title: 'Components/Button', - component: fluentButton, - argTypes: { - appearance: { - description: 'This controls the basic appearances', - control: { type: 'select' }, - options: ['neutral', 'accent', 'lightweight', 'outline', 'stealth'], - default: 'neutral', - }, - disabled: { - control: { type: 'boolean' }, - }, - }, -}; - -const ButtonTemplate = ({ appearance, disabled, label }) => - ` - - ${label} - - `; - -export const Button = ButtonTemplate.bind({}); - -Button.args = { - label: 'Button', - disabled: false, - appearance: 'accent', -}; - -const example = ` -Button -`; - -Button.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/button/button.styles.ts b/packages/web-components/src/button/button.styles.ts deleted file mode 100644 index 58fe6ae60e28f..0000000000000 --- a/packages/web-components/src/button/button.styles.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - disabledCursor, - ElementDefinitionContext, - FoundationElementDefinition, -} from '@microsoft/fast-foundation'; -import { - AccentButtonStyles, - baseButtonStyles, - LightweightButtonStyles, - NeutralButtonStyles, - OutlineButtonStyles, - StealthButtonStyles, -} from '../styles/'; -import { appearanceBehavior } from '../utilities/behaviors'; -import { disabledOpacity } from '../design-tokens'; - -const interactivitySelector: string = ':not([disabled])'; -const nonInteractivitySelector: string = '[disabled]'; - -export const buttonStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - :host(${interactivitySelector}) .control { - cursor: pointer; - } - - :host(${nonInteractivitySelector}) .control { - cursor: ${disabledCursor}; - } - - @media (forced-colors: none) { - :host(${nonInteractivitySelector}) .control { - opacity: ${disabledOpacity}; - } - } - - ${baseButtonStyles(context, definition, interactivitySelector, nonInteractivitySelector)} - `.withBehaviors( - appearanceBehavior('neutral', NeutralButtonStyles(context, definition, interactivitySelector, nonInteractivitySelector)), - appearanceBehavior('accent', AccentButtonStyles(context, definition, interactivitySelector, nonInteractivitySelector)), - appearanceBehavior('lightweight', LightweightButtonStyles(context, definition, interactivitySelector, nonInteractivitySelector)), - appearanceBehavior('outline', OutlineButtonStyles(context, definition, interactivitySelector, nonInteractivitySelector)), - appearanceBehavior('stealth', StealthButtonStyles(context, definition, interactivitySelector, nonInteractivitySelector)), - ); diff --git a/packages/web-components/src/button/button.vscode.definition.json b/packages/web-components/src/button/button.vscode.definition.json deleted file mode 100644 index de8927df390e1..0000000000000 --- a/packages/web-components/src/button/button.vscode.definition.json +++ /dev/null @@ -1,158 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-button", - "title": "Button", - "description": "The Fluent UI button element", - "attributes": [ - { - "name": "appearance", - "title": "Appearance", - "description": "The button's visual treatment", - "type": "string", - "values": [ - { - "name": "accent" - }, - { - "name": "lightweight" - }, - { - "name": "neutral" - }, - { - "name": "outline" - }, - { - "name": "stealth" - } - ], - "default": "neutral", - "required": false - }, - { - "name": "autofocus", - "title": "Autofocus", - "description": "Determines if the element should receive document focus on page load", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Sets the disabled state of the button", - "type": "boolean", - "required": false - }, - { - "name": "form", - "title": "Form ID", - "description": "The ID of a form to associate the element to", - "type": "string", - "required": false - }, - { - "name": "formaction", - "title": "Form processing url", - "description": "The HTML formaction attribute of the button", - "type": "string", - "required": false - }, - { - "name": "formenctype", - "title": "Form encoding", - "description": "The HTML formenctype attribute of the button", - "type": "string", - "required": false - }, - { - "name": "formmethod", - "title": "Form submit method", - "description": "The HTML formmethod attribute of the button", - "type": "string", - "required": false, - "values": [{ "name": "post" }, { "name": "get" }] - }, - { - "name": "formnovalidate", - "title": "No form validation", - "description": "The HTML formnovalidate attribute of the button", - "type": "boolean", - "required": false - }, - { - "name": "formtarget", - "title": "Form Target", - "description": "The HTML formtarget attribute of the button", - "type": "string", - "values": [ - { - "name": "_self" - }, - { - "name": "_blank" - }, - { - "name": "_parent" - }, - { - "name": "_top" - } - ], - "required": false - }, - { - "name": "name", - "title": "Name", - "description": "The HTML name attribute of the button", - "type": "string", - "required": false - }, - { - "name": "type", - "title": "Type", - "description": "The HTML type attribute of the button", - "type": "string", - "required": false, - "values": [ - { - "name": "submit" - }, - { - "name": "reset" - }, - { - "name": "button" - } - ] - }, - { - "name": "value", - "title": "Value", - "description": "The HTML value attribute of the button", - "type": "string", - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the anchor" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned before the button content" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the button content" - } - ] - } - ] -} diff --git a/packages/web-components/src/button/fixtures/button.html b/packages/web-components/src/button/fixtures/button.html deleted file mode 100644 index 74d45ab844abb..0000000000000 --- a/packages/web-components/src/button/fixtures/button.html +++ /dev/null @@ -1,117 +0,0 @@ - - -

Button

-

enabled / disabled

- -

Default

-
- Button - Button -
- -
autofocus
-
- Button - Button -
- -

Neutral

-
- Button - Button -
- -

Accent

-
- Button - Button -
- -

Lightweight

-
- Button - Button -
- -

Outline

-
- Button - Button -
- -

Stealth

-
- Button - Button -
- -

With start

-
- - Button - - - - - - Button - - - - -
- -

With end

-
- - Button - - - - - - Button - - - - -
- -

Icon in default slot

-
- - - - - - - - - - -
- -

With aria-label

-
- Button - Button -
diff --git a/packages/web-components/src/button/index.ts b/packages/web-components/src/button/index.ts deleted file mode 100644 index 14eb16e35363a..0000000000000 --- a/packages/web-components/src/button/index.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { attr } from '@microsoft/fast-element'; -import { Button as FoundationButton, buttonTemplate as template } from '@microsoft/fast-foundation'; -import { buttonStyles as styles } from './button.styles'; - -/** - * Types of button appearance. - * @public - */ -export type ButtonAppearance = 'accent' | 'lightweight' | 'neutral' | 'outline' | 'stealth'; - -/** - * The Fluent button class - * @internal - */ -export class Button extends FoundationButton { - /** - * The appearance the button should have. - * - * @public - * @remarks - * HTML Attribute: appearance - */ - @attr - public appearance: ButtonAppearance; - public appearanceChanged(oldValue: ButtonAppearance, newValue: ButtonAppearance): void { - if (oldValue !== newValue) { - this.classList.add(newValue); - this.classList.remove(oldValue); - } - } - - /** - * @internal - */ - public connectedCallback(): void { - super.connectedCallback(); - - if (!this.appearance) { - this.appearance = 'neutral'; - } - } - - /** - * Applies 'icon-only' class when there is only an SVG in the default slot - * - * @internal - */ - public defaultSlottedContentChanged(): void { - const slottedElements = this.defaultSlottedContent.filter(x => x.nodeType === Node.ELEMENT_NODE); - - if (slottedElements.length === 1 && slottedElements[0] instanceof SVGElement) { - this.control.classList.add('icon-only'); - } else { - this.control.classList.remove('icon-only'); - } - } -} - -/** - * The Fluent Button Element. Implements {@link @microsoft/fast-foundation#Button}, - * {@link @microsoft/fast-foundation#buttonTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - * - * {@link https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus | delegatesFocus} - */ -export const fluentButton = Button.compose({ - baseName: 'button', - baseClass: FoundationButton, - template, - styles, - shadowOptions: { - delegatesFocus: true, - }, -}); - -/** - * Styles for Button - * @public - */ -export const buttonStyles = styles; diff --git a/packages/web-components/src/calendar/calendar.stories.ts b/packages/web-components/src/calendar/calendar.stories.ts deleted file mode 100644 index fd5f4192577c6..0000000000000 --- a/packages/web-components/src/calendar/calendar.stories.ts +++ /dev/null @@ -1,136 +0,0 @@ -import './index'; -import { fluentCalendar } from './index'; - -const now = new Date(); -const years = new Array(9).fill(null).map((_, index) => (now.getFullYear() - 4 + index).toString()); -const groupsToDates = matrix => - matrix.map(days => days.map(day => `${now.getMonth() + 1}-${day}-${now.getFullYear()}`).join(',')); -const disabledDates = groupsToDates([ - [1, 2, 3, 4, now.getDate()], - [6, 7, 10, 18], - [8, 17, 24, 25], - [4, 11, 18, 25], -]); - -export default { - title: 'Components/Calendar', - component: fluentCalendar, - argTypes: { - month: { - description: 'Month of the calendar to display.', - control: { type: 'select' }, - options: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], - default: 'The current month', - }, - year: { - description: 'Year of the calendar to display.', - control: { type: 'select' }, - options: years, - default: 'The current year', - }, - locale: { - control: { type: 'select' }, - options: ['en-US', 'fr-FR', 'de-DE', 'th-TH-u-ca-buddhist-nu-thai', 'ar-XE-u-ca-islamic-nu-arab'], - default: 'en-US', - description: - 'Locale information which can include market (language and country), calendar type and numbering type.', - }, - dayFormat: { - description: 'Formatting for the numbered days.', - options: ['2-digit', 'numeric'], - control: { type: 'select' }, - default: 'numeric', - }, - weekdayFormat: { - description: 'Formatting for the weekday titles.', - options: ['long', 'narrow', 'short'], - control: { type: 'select' }, - default: 'short', - }, - monthFormat: { - description: 'Formatting for the month name in the title.', - options: ['2-digit', 'long', 'narrow', 'numeric', 'short'], - control: { type: 'select' }, - default: 'long', - }, - yearFormat: { - description: 'Formatting for the year in the title.', - options: ['2-digit', 'numeric'], - control: { type: 'select' }, - default: 'numeric', - }, - disabledDates: { - description: 'Dates to be shown as disabled.', - options: disabledDates, - control: { type: 'select' }, - }, - selectedDates: { - description: 'Dates to be shown as selected', - options: disabledDates, - control: { type: 'select' }, - }, - readonly: { - description: 'A readonly version of the calendar without AT interactions.', - control: { type: 'boolean' }, - default: true, - }, - }, -}; - -const CalendarTemplate = ({ - month, - year, - locale, - dayFormat, - weekdayFormat, - monthFormat, - yearFormat, - disabledDates, - selectedDates, - readonly, -}) => - ` - - - `; - -export const Calendar = CalendarTemplate.bind({}); - -Calendar.args = { - label: 'Calendar', - month: (now.getMonth() + 1).toString(), - year: now.getFullYear().toString(), - locale: 'en-US', - readonly: true, - dayFormat: 'numeric', - weekdayFormat: 'short', - monthFormat: 'long', - yearFormat: 'numeric', -}; - -const example = ` - - `; - -Calendar.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/calendar/calendar.styles.ts b/packages/web-components/src/calendar/calendar.styles.ts deleted file mode 100644 index ad2ddf18d3b3b..0000000000000 --- a/packages/web-components/src/calendar/calendar.styles.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { css, ElementStyles } from "@microsoft/fast-element"; -import { - display, - ElementDefinitionContext, - forcedColorsStylesheetBehavior, - FoundationElementDefinition -} from '@microsoft/fast-foundation'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { - accentFillRest, - baseHeightMultiplier, - controlCornerRadius, - density, - designUnit, - fillColor, - foregroundOnAccentRest, - neutralForegroundHint, - neutralForegroundRest, - strokeWidth, -} from '../design-tokens'; -import { DirectionalStyleSheetBehavior } from '../styles'; -import { typeRampBase } from '../styles/patterns/type-ramp'; - -/** - * LTR styles for calendar - * @internal - */ -const ltrStyles = css` -.day.disabled::before { - transform: translate(-50%, 0) rotate(45deg); -} -`; - -/** - * RTL styles for calendar - * @internal - */ -const rtlStyles = css` -.day.disabled::before { - transform: translate(50%, 0) rotate(-45deg); -} -`; - -/** - * Styles for calendar - * @public - */ -export const calendarStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition -) => ElementStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition -) => css` -${display("inline-block")} :host { - --calendar-cell-size: calc((${baseHeightMultiplier} + 2 + ${density}) * ${designUnit} * 1px); - --calendar-gap: 2px; - ${typeRampBase} - color: ${neutralForegroundRest}; -} - -.title { - padding: calc(${designUnit} * 2px); - font-weight: 600; -} - -.days { - text-align: center; -} - -.week-days, -.week { - display: grid; - grid-template-columns: repeat(7, 1fr); - grid-gap: var(--calendar-gap); - border: 0; - padding: 0; -} - -.day, -.week-day { - border: 0; - width: var(--calendar-cell-size); - height: var(--calendar-cell-size); - line-height: var(--calendar-cell-size); - padding: 0; - box-sizing: initial; -} - -.week-day { - font-weight: 600; -} - -.day { - border: calc(${strokeWidth} * 1px) solid transparent; - border-radius: calc(${controlCornerRadius} * 1px); -} - -.interact .day { - cursor: pointer; -} - -.date { - height: 100%; -} - -.inactive .date, -.inactive.disabled::before { - color: ${neutralForegroundHint}; -} - -.disabled::before { - content: ''; - display: inline-block; - width: calc(var(--calendar-cell-size) * .8); - height: calc(${strokeWidth} * 1px); - background: currentColor; - position: absolute; - margin-top: calc(var(--calendar-cell-size) / 2); - transform-origin: center; - z-index: 1; -} - -.selected { - color: ${accentFillRest}; - border: 1px solid ${accentFillRest}; - background: ${fillColor}; -} - -.selected + .selected { - border-start-start-radius: 0; - border-end-start-radius: 0; - border-inline-start-width: 0; - padding-inline-start: calc(var(--calendar-gap) + (${strokeWidth} + ${controlCornerRadius}) * 1px); - margin-inline-start: calc((${controlCornerRadius} * -1px) - var(--calendar-gap)); -} - -.today.disabled::before { - color: ${foregroundOnAccentRest}; -} - -.today .date { - color: ${foregroundOnAccentRest}; - background: ${accentFillRest}; - border-radius: 50%; - position: relative; -} -`.withBehaviors( - forcedColorsStylesheetBehavior( - css` - .day.selected { - color: ${SystemColors.Highlight}; - } - - .today .date { - background: ${SystemColors.Highlight}; - color: ${SystemColors.HighlightText}; - } - ` - ), - new DirectionalStyleSheetBehavior(ltrStyles, rtlStyles) -); diff --git a/packages/web-components/src/calendar/calendar.vscode.definition.json b/packages/web-components/src/calendar/calendar.vscode.definition.json deleted file mode 100644 index 0fa3c093a925b..0000000000000 --- a/packages/web-components/src/calendar/calendar.vscode.definition.json +++ /dev/null @@ -1,156 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-calendar", - "title": "Calendar", - "description": "Adds Fluent UI calendar element", - "attributes": [ - { - "name": "day-format", - "title": "Day format", - "description": "The rendering style for the days in the calendar.", - "type": "string", - "default": "numeric", - "required": false, - "values": [ - { - "name": "2-digit" - }, - { - "name": "numeric" - } - ] - }, - { - "name": "disabled-dates", - "title": "Disabled dates", - "description": "A comma separated list of dates to show as disabled.", - "type": "string", - "required": false - }, - { - "name": "locale", - "title": "Locale", - "description": "Locale information for the calendar. This will include language, country, calendar type and numbering type. Defaults to browser locale.", - "type": "string", - "default": "", - "required": false - }, - { - "name": "min-weeks", - "title": "Minimum weeks", - "description": "Minimum number of weeks to display in the calendar. Used for normalizing across different months.", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "month", - "title": "Month", - "description": "Month of the calendar to render. The default will be the current month.", - "type": "number", - "required": false - }, - { - "name": "month-format", - "title": "Month format", - "description": "The rendering style for the month name. Values include short, long and narrow.", - "type": "string", - "values": [ - { - "name": "long" - }, - { - "name": "narrow" - }, - { - "name": "short" - } - ], - "default": "long", - "required": false - }, - { - "name": "readonly", - "title": "Read only", - "description": "If there is not interactions for the calendar", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "selected-dates", - "title": "Selected dates", - "description": "A comma separated list of dates to show as highlighted.", - "type": "string", - "required": false - }, - { - "name": "weekday-format", - "title": "Weekday format", - "description": "The rendering style for the weekday labels. Values include short, long and narrow.", - "type": "string", - "values": [ - { - "name": "long" - }, - { - "name": "narrow" - }, - { - "name": "short" - } - ], - "default": "short", - "required": false - }, - { - "name": "year", - "title": "Year", - "description": "Year of the calendar to render. The default will be the current year.", - "type": "number", - "required": false - }, - { - "name": "year-format", - "title": "Year format", - "description": "Formatting for the year in the title", - "type": "string", - "values": [ - { - "name": "numeric" - }, - { - "name": "2-digit" - } - ], - "default": "numeric", - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the calendar added to the beginning of the title container" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the calendar" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned before the calendar" - }, - { - "name": "title", - "title": "Title slot", - "description": "Title with month and year that can be replaced." - } - ] - } - ] -} diff --git a/packages/web-components/src/calendar/index.ts b/packages/web-components/src/calendar/index.ts deleted file mode 100644 index d8b684618e53d..0000000000000 --- a/packages/web-components/src/calendar/index.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { attr, booleanConverter } from '@microsoft/fast-element'; -import { - CalendarOptions, - CalendarTitleTemplate, - Calendar as FoundationCalendar, - calendarTemplate as template, -} from '@microsoft/fast-foundation'; -import { calendarStyles as styles } from './calendar.styles'; - -/** - * Updated Calendar class that is readonly by default - */ -export class Calendar extends FoundationCalendar { - @attr({ converter: booleanConverter }) - public readonly: boolean = true; -} - -/** - * The Fluent Calendar Element. Implements {@link @microsoft/fast-foundation#Calendar}, - * {@link @microsoft/fast-foundation#calendarTemplate} - * - * @public - * @remarks - * HTML Element \ - */ -export const fluentCalendar = Calendar.compose({ - baseName: 'calendar', - template, - styles, - title: CalendarTitleTemplate, -}); - -export { styles as calendarStyles }; diff --git a/packages/web-components/src/card/README.md b/packages/web-components/src/card/README.md deleted file mode 100644 index 0bff708731241..0000000000000 --- a/packages/web-components/src/card/README.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -id: card -title: fluent-card -sidebar_label: card -custom_edit_url: https://github.com/microsoft/fluentui/edit/master/packages/web-components/src/card/README.md ---- - -The `fluent-card` component is a visual container and design system provider. By default `fluent-card` applies `neutralFillCard` to its background that is calculated from its parent design system provider. If a custom background color is desired the attribute `card-background-color` is available, this will reset the cards design system to that value. Cards are snapshots of content that are typically used in a group to present collections of related information. - -## Usage - -```html live - - -

Card title

-

- At purus lectus quis habitant commodo, cras. Aliquam malesuada velit a tortor. Felis orci tellus netus risus et - ultricies augue aliquet. -

- Learn more -
-
- - - -

Card title

-

- At purus lectus quis habitant commodo, cras. Aliquam malesuada velit a tortor. Felis orci tellus netus risus et - ultricies augue aliquet. -

- Learn more -
-
-``` diff --git a/packages/web-components/src/card/card.stories.ts b/packages/web-components/src/card/card.stories.ts deleted file mode 100644 index ce5f4cee07dd7..0000000000000 --- a/packages/web-components/src/card/card.stories.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { addons } from '@storybook/addons'; -import { DOCS_RENDERED } from '@storybook/core-events'; -import { DesignSystemProvider, StandardLuminance } from '../index-rollup'; -import CardTemplate from './fixtures/card.html'; -import './index'; - -addons.getChannel().addListener(DOCS_RENDERED, name => { - if (name.toLowerCase().includes('card')) { - const els = document.getElementsByClassName('darkMode'); - for (let i = 0; i < els.length; i++) { - const el = els[i]; - if (el instanceof DesignSystemProvider) { - el.baseLayerLuminance = StandardLuminance.DarkMode; - } - } - } -}); - -export default { - title: 'Components/Card', -}; - -export const Card = (): string => CardTemplate; - -const example = ` -Card content in default slot -`; - -Card.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/card/card.styles.ts b/packages/web-components/src/card/card.styles.ts deleted file mode 100644 index 2d937e8f97ba0..0000000000000 --- a/packages/web-components/src/card/card.styles.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - display, - ElementDefinitionContext, - forcedColorsStylesheetBehavior, - FoundationElementDefinition, -} from '@microsoft/fast-foundation'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { - fillColor, - layerCornerRadius, - neutralForegroundRest, - neutralStrokeLayerRest, - strokeWidth, -} from '../design-tokens'; -import { elevationShadowCardRest } from '../styles'; - -export const cardStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - ${display('block')} :host { - display: block; - contain: content; - height: var(--card-height, 100%); - width: var(--card-width, 100%); - box-sizing: border-box; - background: ${fillColor}; - color: ${neutralForegroundRest}; - border: calc(${strokeWidth} * 1px) solid ${neutralStrokeLayerRest}; - border-radius: calc(${layerCornerRadius} * 1px); - box-shadow: ${elevationShadowCardRest}; - } - - :host { - content-visibility: auto; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host { - background: ${SystemColors.Canvas}; - color: ${SystemColors.CanvasText}; - } - `, - ), - ); diff --git a/packages/web-components/src/card/card.vscode.definition.json b/packages/web-components/src/card/card.vscode.definition.json deleted file mode 100644 index dd462ed9495e1..0000000000000 --- a/packages/web-components/src/card/card.vscode.definition.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-card", - "title": "Card", - "description": "The Fluent UI card element", - "attributes": [ - { - "name": "card-fill-color", - "title": "Card fill color", - "description": "The fill color for the card, which also sets context for the design system.", - "type": "string", - "required": false - }, - { - "name": "neutral-palette-source", - "title": "Neutral Palette Source", - "description": "The neutral palette source color for the card component to allow tinting, which also sets context for the design system", - "type": "string", - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the card" - } - ] - } - ] -} diff --git a/packages/web-components/src/card/fixtures/card.html b/packages/web-components/src/card/fixtures/card.html deleted file mode 100644 index 75c891f8fc31f..0000000000000 --- a/packages/web-components/src/card/fixtures/card.html +++ /dev/null @@ -1,123 +0,0 @@ - -
- Custom size using CSS - - - -
-

Dark

- Accent - Stealth - Outline - Lightweight -
-
-
- - - -
-

Tinted neutral-palette-source, dark container

- Accent - Stealth - Outline - Lightweight -
-
-
- - - -
-

Tinted neutral-palette-source, dark

- Accent - Stealth - Outline - Lightweight -
-
-
- - - -
-

Tinted neutral-palette-source, dark

- Accent - Stealth - Outline - Lightweight -
- -
-

Tinted neutral-palette-source, nested, dark

- Accent - Stealth - Outline - Lightweight -
-
-
-
- - -
-

Custom card-fill-color

- Accent - Stealth - Outline - Lightweight -

- Note the stealth buttons have a slight fill, which is because the card-fill-color is explicit, but the stealth - recipe gets its value from the neutral palette which has been created based on the card-fill-color, but does not - contain that exact color. -

-
-
- - - -
-

Accent and neutral color by DSP

- Accent - Neutral - Stealth - Outline - Lightweight -
-
-
-
diff --git a/packages/web-components/src/card/index.ts b/packages/web-components/src/card/index.ts deleted file mode 100644 index bace44d9e5af3..0000000000000 --- a/packages/web-components/src/card/index.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { composedParent, Card as FoundationCard, cardTemplate as template } from '@microsoft/fast-foundation'; -import { attr, Notifier, Observable } from '@microsoft/fast-element'; -import { parseColorHexRGB } from '@microsoft/fast-colors'; -import { fillColor, neutralFillLayerRecipe, neutralPalette } from '../design-tokens'; -import { Swatch, SwatchRGB } from '../color/swatch'; -import { PaletteRGB } from '../color/palette'; -import { cardStyles as styles } from './card.styles'; - -/** - * @public - */ -export class Card extends FoundationCard { - /** - * Fill color for the card component. Sets context for the design system. - * - * Updates the neutral palette and sets the card to the source color. For tinting use neutral-palette-source instead. - * @public - * @remarks - * HTML Attribute: card-fill-color - */ - @attr({ - attribute: 'card-fill-color', - mode: 'fromView', - }) - public cardFillColor: string; - private cardFillColorChanged(prev: string | void, next: string | void): void { - if (next) { - const parsedColor = parseColorHexRGB(next); - - if (parsedColor !== null) { - this.neutralPaletteSource = next; - fillColor.setValueFor(this, SwatchRGB.create(parsedColor.r, parsedColor.g, parsedColor.b)); - } - } - } - - /** - * Neutral palette source color for the card component. Sets context for the design system. - * - * This allows for tinting the card while maintaining the light or dark context. For a fixed color use card-fill-color instead. - * @public - * @remarks - * HTML Attribute: neutral-palette-source - */ - @attr({ - attribute: 'neutral-palette-source', - mode: 'fromView', - }) - public neutralPaletteSource: string; - private neutralPaletteSourceChanged(prev: string | void, next: string | void): void { - if (next) { - const color = parseColorHexRGB(next)!; - const swatch = SwatchRGB.create(color.r, color.g, color.b); - neutralPalette.setValueFor(this, PaletteRGB.create(swatch)); - } - } - - /** - * @internal - */ - public handleChange(source: any, propertyName: string): void { - if (!this.cardFillColor) { - fillColor.setValueFor( - this, - (target: HTMLElement): Swatch => - neutralFillLayerRecipe.getValueFor(target).evaluate(target, fillColor.getValueFor(source)).rest, - ); - } - } - - connectedCallback(): void { - super.connectedCallback(); - - const parent = composedParent(this); - - if (parent) { - const parentNotifier: Notifier = Observable.getNotifier(parent); - parentNotifier.subscribe(this, 'fillColor'); - parentNotifier.subscribe(this, 'neutralPalette'); - this.handleChange(parent, 'fillColor'); - } - } -} - -/** - * The Fluent Card Element. Implements {@link @microsoft/fast-foundation#Card}, - * {@link @microsoft/fast-foundation#CardTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentCard = Card.compose({ - baseName: 'card', - baseClass: FoundationCard, - template, - styles, -}); - -/** - * Styles for Card - * @public - */ -export const cardStyles = styles; diff --git a/packages/web-components/src/checkbox/checkbox.stories.ts b/packages/web-components/src/checkbox/checkbox.stories.ts deleted file mode 100644 index a92765c71b41d..0000000000000 --- a/packages/web-components/src/checkbox/checkbox.stories.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { fluentCheckbox } from './index'; - -export default { - title: 'Components/Checkbox', - component: fluentCheckbox, - argTypes: { - checked: { - control: { type: 'boolean' }, - }, - disabled: { - control: { type: 'boolean' }, - }, - required: { - control: { type: 'boolean' }, - }, - }, - parameters: { - actions: { - handles: ['mouseover', 'click'], - }, - }, -}; - -const CheckboxTemplate = ({ checked, disabled, label, required }) => - `${label}`; - -export const Checkbox = CheckboxTemplate.bind({}); - -Checkbox.args = { - label: 'Label string', - checked: false, - disabled: false, - required: false, -}; - -const example = ` -Label string -`; - -Checkbox.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/checkbox/checkbox.styles.ts b/packages/web-components/src/checkbox/checkbox.styles.ts deleted file mode 100644 index 589c2233b68bf..0000000000000 --- a/packages/web-components/src/checkbox/checkbox.styles.ts +++ /dev/null @@ -1,196 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - CheckboxOptions, - disabledCursor, - display, - ElementDefinitionContext, - focusVisible, - forcedColorsStylesheetBehavior, -} from '@microsoft/fast-foundation'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { heightNumber } from '../styles'; -import { - accentFillActive, - accentFillHover, - accentFillRest, - controlCornerRadius, - designUnit, - disabledOpacity, - foregroundOnAccentRest, - neutralFillInputAltActive, - neutralFillInputAltFocus, - neutralFillInputAltHover, - neutralFillInputAltRest, - neutralForegroundRest, - neutralStrokeStrongActive, - neutralStrokeStrongHover, - neutralStrokeStrongRest, - strokeWidth, -} from '../design-tokens'; -import { typeRampBase } from '../styles/patterns/type-ramp'; -import { focusTreatmentTight } from '../styles/focus'; - -export const checkboxStyles: (context: ElementDefinitionContext, definition: CheckboxOptions) => ElementStyles = ( - context: ElementDefinitionContext, - definition: CheckboxOptions, -) => - css` - ${display('inline-flex')} :host { - align-items: center; - outline: none; - ${ - /* - * Chromium likes to select label text or the default slot when - * the checkbox is clicked. Maybe there is a better solution here? - */ '' - } user-select: none; - } - - .control { - position: relative; - width: calc((${heightNumber} / 2 + ${designUnit}) * 1px); - height: calc((${heightNumber} / 2 + ${designUnit}) * 1px); - box-sizing: border-box; - border-radius: calc(${controlCornerRadius} * 1px); - border: calc(${strokeWidth} * 1px) solid ${neutralStrokeStrongRest}; - background: ${neutralFillInputAltRest}; - cursor: pointer; - } - - .label__hidden { - display: none; - visibility: hidden; - } - - .label { - ${typeRampBase} - color: ${neutralForegroundRest}; - ${ - /* Need to discuss with Brian how HorizontalSpacingNumber can work. https://github.com/microsoft/fast/issues/2766 */ '' - } padding-inline-start: calc(${designUnit} * 2px + 2px); - margin-inline-end: calc(${designUnit} * 2px + 2px); - cursor: pointer; - } - - slot[name='checked-indicator'], - slot[name='indeterminate-indicator'] { - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; - fill: ${neutralForegroundRest}; - opacity: 0; - pointer-events: none; - } - - slot[name='indeterminate-indicator'] { - position: absolute; - top: 0; - } - - :host(.checked) slot[name='checked-indicator'], - :host(.checked) slot[name='indeterminate-indicator'] { - fill: ${foregroundOnAccentRest}; - } - - :host(:not(.disabled):hover) .control { - background: ${neutralFillInputAltHover}; - border-color: ${neutralStrokeStrongHover}; - } - - :host(:not(.disabled):active) .control { - background: ${neutralFillInputAltActive}; - border-color: ${neutralStrokeStrongActive}; - } - - :host(:${focusVisible}) .control { - background: ${neutralFillInputAltFocus}; - ${focusTreatmentTight} - } - - :host(.checked) .control { - background: ${accentFillRest}; - border-color: transparent; - } - - :host(.checked:not(.disabled):hover) .control { - background: ${accentFillHover}; - border-color: transparent; - } - - :host(.checked:not(.disabled):active) .control { - background: ${accentFillActive}; - border-color: transparent; - } - - :host(.disabled) .label, - :host(.readonly) .label, - :host(.readonly) .control, - :host(.disabled) .control { - cursor: ${disabledCursor}; - } - - :host(.checked:not(.indeterminate)) slot[name='checked-indicator'], - :host(.indeterminate) slot[name='indeterminate-indicator'] { - opacity: 1; - } - - :host(.disabled) { - opacity: ${disabledOpacity}; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - .control { - border-color: ${SystemColors.FieldText}; - background: ${SystemColors.Field}; - } - :host(:not(.disabled):hover) .control, - :host(:not(.disabled):active) .control { - border-color: ${SystemColors.Highlight}; - background: ${SystemColors.Field}; - } - slot[name='checked-indicator'], - slot[name='indeterminate-indicator'] { - fill: ${SystemColors.FieldText}; - } - :host(:${focusVisible}) .control { - forced-color-adjust: none; - outline-color: ${SystemColors.FieldText}; - background: ${SystemColors.Field}; - border-color: ${SystemColors.Highlight}; - } - :host(.checked) .control { - background: ${SystemColors.Highlight}; - border-color: ${SystemColors.Highlight}; - } - :host(.checked:not(.disabled):hover) .control, - :host(.checked:not(.disabled):active) .control { - background: ${SystemColors.HighlightText}; - border-color: ${SystemColors.Highlight}; - } - :host(.checked) slot[name='checked-indicator'], - :host(.checked) slot[name='indeterminate-indicator'] { - fill: ${SystemColors.HighlightText}; - } - :host(.checked:hover ) .control slot[name='checked-indicator'], - :host(.checked:hover ) .control slot[name='indeterminate-indicator'] { - fill: ${SystemColors.Highlight}; - } - :host(.disabled) { - opacity: 1; - } - :host(.disabled) .control { - border-color: ${SystemColors.GrayText}; - background: ${SystemColors.Field}; - } - :host(.disabled) slot[name='checked-indicator'], - :host(.checked.disabled:hover) .control slot[name='checked-indicator'], - :host(.disabled) slot[name='indeterminate-indicator'], - :host(.checked.disabled:hover) .control slot[name='indeterminate-indicator'] { - fill: ${SystemColors.GrayText}; - } - `, - ), - ); diff --git a/packages/web-components/src/checkbox/checkbox.vscode.definition.json b/packages/web-components/src/checkbox/checkbox.vscode.definition.json deleted file mode 100644 index eed93e4fd7853..0000000000000 --- a/packages/web-components/src/checkbox/checkbox.vscode.definition.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-checkbox", - "title": "Checkbox", - "description": "The Fluent UI checkbox element", - "attributes": [ - { - "name": "checked", - "title": "Checked", - "description": "Whether or not this checkbox is checked by default", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "name", - "title": "Name", - "description": "This element's value will be surfaced during form submission under the provided name", - "type": "string", - "default": "", - "required": false - }, - { - "name": "required", - "title": "Required", - "description": "Require the field to be completed prior to form submission", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Sets the disabled state of the checkbox", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "readonly", - "title": "Readonly", - "description": "When true, the control will be immutable by user interaction", - "type": "boolean", - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the checkbox represents its visual label" - }, - { - "name": "indeterminate-indicator", - "title": "Indeterminate indicator slot", - "description": "Slot to provide a custom icon to represent the inditerminate state" - }, - { - "name": "checked-indicator", - "title": "Checked indicator slot", - "description": "Slot to provide a custom icon to represent the checked state" - } - ] - } - ] -} diff --git a/packages/web-components/src/checkbox/fixtures/checkbox.html b/packages/web-components/src/checkbox/fixtures/checkbox.html deleted file mode 100644 index 50980745601a3..0000000000000 --- a/packages/web-components/src/checkbox/fixtures/checkbox.html +++ /dev/null @@ -1,43 +0,0 @@ -

Checkbox

-

Default

- -label - -

Checked

- - - -

Required

- - -

Indeterminate

-Unchecked -Checked - - -

Disabled

- -label -checked - Indeterminate checked - Indeterminate unchecked - -

Inline

-Apples -Bananas -Honeydew -Oranges - -

Vertical

-
- Fruit - Apples - Bananas - Honeydew - Oranges -
- -

Visual vs audio label

- - Visible label - diff --git a/packages/web-components/src/checkbox/index.ts b/packages/web-components/src/checkbox/index.ts deleted file mode 100644 index cbd76e93cbea1..0000000000000 --- a/packages/web-components/src/checkbox/index.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Checkbox, CheckboxOptions, checkboxTemplate as template } from '@microsoft/fast-foundation'; -import { checkboxStyles as styles } from './checkbox.styles'; - -/** - * The Fluent Checkbox Element. Implements {@link @microsoft/fast-foundation#Checkbox}, - * {@link @microsoft/fast-foundation#checkboxTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentCheckbox = Checkbox.compose({ - baseName: 'checkbox', - template, - styles, - checkedIndicator: ` - - - - `, - indeterminateIndicator: ` - - - - `, -}); - -/** - * Styles for Checkbox - * @public - */ -export const checkboxStyles = styles; diff --git a/packages/web-components/src/color/README.md b/packages/web-components/src/color/README.md deleted file mode 100644 index 02586f1f9ca90..0000000000000 --- a/packages/web-components/src/color/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# Fluent Color Recipes - -Color recipes are named colors who's value is algorithmically defined from a variety of inputs. `@fluentui/web-components` relies on these recipes heavily to achieve expressive theming options while maintaining color accessability targets. - -## Swatch - -A Swatch is a representation of a color that has a `relativeLuminance` value and a method to convert the swatch to a color string. It is used by recipes to determine which colors to use for UI. - -### SwatchRGB - -A concrete implementation of `Swatch`, it is a swatch with red, green, and blue 64bit color channels . - -**Example: Creating a SwatchRGB** - -```ts -import { SwatchRGB } from '@fluentui/web-components'; - -const red = SwatchRGB.create(1, 0, 0); -``` - -## Palette - -A palette is a collection `Swatch` instances, ordered by relative luminance, and provides mechanisms to safely retrieve swatches by index and by target contrast ratios. It also contains a `source` color, which is the color from which the palette is - -### PaletteRGB - -An implementation of `Palette` of `SwatchRGB` instances. - -```ts -// Create a palette from the red swatch -const palette = PaletteRGB.create(red): -``` diff --git a/packages/web-components/src/color/palette.ts b/packages/web-components/src/color/palette.ts deleted file mode 100644 index 4773f0cb20ef7..0000000000000 --- a/packages/web-components/src/color/palette.ts +++ /dev/null @@ -1,401 +0,0 @@ -import { - clamp, - ColorHSL, - ColorLAB, - ColorRGBA64, - hslToRGB, - interpolateRGB, - labToRGB, - rgbToHSL, - rgbToLAB, - roundToPrecisionSmall, -} from '@microsoft/fast-colors'; -import { isSwatchRGB, Swatch, SwatchRGB } from './swatch'; -import { binarySearch } from './utilities/binary-search'; -import { directionByIsDark } from './utilities/direction-by-is-dark'; -import { contrast, RelativeLuminance } from './utilities/relative-luminance'; - -/** - * A collection of {@link Swatch} instances - * @public - */ -export interface Palette { - readonly source: T; - readonly swatches: ReadonlyArray; - - /** - * Returns a swatch from the palette that most closely matches - * the contrast ratio provided to a provided reference. - */ - colorContrast(reference: Swatch, contrast: number, initialIndex?: number, direction?: 1 | -1): T; - - /** - * Returns the index of the palette that most closely matches - * the relativeLuminance of the provided swatch - */ - closestIndexOf(reference: RelativeLuminance): number; - - /** - * Gets a swatch by index. Index is clamped to the limits - * of the palette so a Swatch will always be returned. - */ - get(index: number): T; -} - -/** - * Options to tailor the generation of the color palette. - * @public - */ -export interface PaletteRGBOptions { - /** - * The minimum amount of contrast between steps in the palette. Default 1.03. - * Recommended increments by hundredths. - */ - stepContrast: number; - - /** - * Multiplier for increasing step contrast as the swatches darken. Default 0.03. - * Recommended increments by hundredths. - */ - stepContrastRamp: number; - - /** - * Whether to keep the exact source color in the target palette. Default false. - * Only recommended when the exact color is required and used in stateful interaction recipes like hover. - * Note that custom recipes can still access the source color even if it's not in the ramp, - * but turning this on will potentially increase the contrast between steps toward the ends of the palette. - */ - preserveSource: boolean; -} - -const defaultPaletteRGBOptions: PaletteRGBOptions = { - stepContrast: 1.03, - stepContrastRamp: 0.03, - preserveSource: false, -}; - -/** @public */ -export type PaletteRGB = Palette; - -/** - * Creates a PaletteRGB from input R, G, B color values. - * @param r - Red value represented as a number between 0 and 1. - * @param g - Green value represented as a number between 0 and 1. - * @param b - Blue value represented as a number between 0 and 1. - */ -function create(r: number, g: number, b: number): PaletteRGB; -/** - * Creates a PaletteRGB from a source SwatchRGB object. - * @deprecated - Use PaletteRGB.from() - */ -function create(source: SwatchRGB): PaletteRGB; -function create(rOrSource: SwatchRGB | number, g?: number, b?: number): PaletteRGB { - if (typeof rOrSource === 'number') { - return PaletteRGB.from(SwatchRGB.create(rOrSource, g!, b!)); - } else { - return PaletteRGB.from(rOrSource); - } -} - -/** - * Creates a PaletteRGB from a source color object. - * @param source - The source color - */ -function from(source: SwatchRGB, options?: Partial): PaletteRGB; -function from(source: Pick, options?: Partial): PaletteRGB { - return isSwatchRGB(source) - ? PaletteRGBImpl.from(source, options) - : PaletteRGBImpl.from(SwatchRGB.create(source.r, source.g, source.b), options); -} -/** @public */ -export const PaletteRGB = Object.freeze({ - create, - from, -}); - -/** - * A {@link Palette} representing RGB swatch values. - * @public - */ -class PaletteRGBImpl implements Palette { - /** - * {@inheritdoc Palette.source} - */ - public readonly source: SwatchRGB; - public readonly swatches: ReadonlyArray; - private lastIndex: number; - private reversedSwatches: ReadonlyArray; - private closestIndexCache = new Map(); - - /** - * - * @param source - The source color for the palette - * @param swatches - All swatches in the palette - */ - constructor(source: SwatchRGB, swatches: ReadonlyArray) { - this.source = source; - this.swatches = swatches; - - this.reversedSwatches = Object.freeze([...this.swatches].reverse()); - this.lastIndex = this.swatches.length - 1; - } - - /** - * {@inheritdoc Palette.colorContrast} - */ - public colorContrast( - reference: Swatch, - contrastTarget: number, - initialSearchIndex?: number, - direction?: 1 | -1, - ): SwatchRGB { - if (initialSearchIndex === undefined) { - initialSearchIndex = this.closestIndexOf(reference); - } - - let source: ReadonlyArray = this.swatches; - const endSearchIndex = this.lastIndex; - let startSearchIndex = initialSearchIndex; - - if (direction === undefined) { - direction = directionByIsDark(reference); - } - - const condition = (value: SwatchRGB) => contrast(reference, value) >= contrastTarget; - - if (direction === -1) { - source = this.reversedSwatches; - startSearchIndex = endSearchIndex - startSearchIndex; - } - - return binarySearch(source, condition, startSearchIndex, endSearchIndex); - } - - /** - * {@inheritdoc Palette.get} - */ - public get(index: number): SwatchRGB { - return this.swatches[index] || this.swatches[clamp(index, 0, this.lastIndex)]; - } - - /** - * {@inheritdoc Palette.closestIndexOf} - */ - public closestIndexOf(reference: Swatch): number { - if (this.closestIndexCache.has(reference.relativeLuminance)) { - return this.closestIndexCache.get(reference.relativeLuminance)!; - } - - let index = this.swatches.indexOf(reference as SwatchRGB); - - if (index !== -1) { - this.closestIndexCache.set(reference.relativeLuminance, index); - return index; - } - - const closest = this.swatches.reduce((previous, next) => - Math.abs(next.relativeLuminance - reference.relativeLuminance) < - Math.abs(previous.relativeLuminance - reference.relativeLuminance) - ? next - : previous, - ); - - index = this.swatches.indexOf(closest); - this.closestIndexCache.set(reference.relativeLuminance, index); - - return index; - } - - /** - * Bump the saturation if it falls below the reference color saturation. - * @param reference Color with target saturation - * @param color Color to check and bump if below target saturation - * @returns Original or adjusted color - */ - private static saturationBump(reference: ColorRGBA64, color: ColorRGBA64): ColorRGBA64 { - const hslReference = rgbToHSL(reference); - const saturationTarget = hslReference.s; - const hslColor = rgbToHSL(color); - if (hslColor.s < saturationTarget) { - const hslNew = new ColorHSL(hslColor.h, saturationTarget, hslColor.l); - return hslToRGB(hslNew); - } - return color; - } - - /** - * Scales input from 0 to 100 to 0 to 0.5. - * @param l Input number, 0 to 100 - * @returns Output number, 0 to 0.5 - */ - private static ramp(l: number) { - const inputval = l / 100; - if (inputval > 0.5) return (inputval - 0.5) / 0.5; //from 0.500001in = 0.00000001out to 1.0in = 1.0out - return 2 * inputval; //from 0in = 0out to 0.5in = 1.0out - } - - /** - * Create a palette following the desired curve and many steps to build a smaller palette from. - * @param source The source swatch to create a palette from - * @returns The palette - */ - private static createHighResolutionPalette(source: SwatchRGB): PaletteRGBImpl { - const swatches: SwatchRGB[] = []; - - const labSource = rgbToLAB(ColorRGBA64.fromObject(source)!.roundToPrecision(4)); - const lab0 = labToRGB(new ColorLAB(0, labSource.a, labSource.b)).clamp().roundToPrecision(4); - const lab50 = labToRGB(new ColorLAB(50, labSource.a, labSource.b)).clamp().roundToPrecision(4); - const lab100 = labToRGB(new ColorLAB(100, labSource.a, labSource.b)).clamp().roundToPrecision(4); - const rgbMin = new ColorRGBA64(0, 0, 0); - const rgbMax = new ColorRGBA64(1, 1, 1); - - const lAbove = lab100.equalValue(rgbMax) ? 0 : 14; - const lBelow = lab0.equalValue(rgbMin) ? 0 : 14; - - // 257 levels max, depending on whether lab0 or lab100 are black or white respectively. - for (let l = 100 + lAbove; l >= 0 - lBelow; l -= 0.5) { - let rgb: ColorRGBA64; - - if (l < 0) { - // For L less than 0, scale from black to L=0 - const percentFromRgbMinToLab0 = l / lBelow + 1; - rgb = interpolateRGB(percentFromRgbMinToLab0, rgbMin, lab0); - } else if (l <= 50) { - // For L less than 50, we scale from L=0 to the base color - rgb = interpolateRGB(PaletteRGBImpl.ramp(l), lab0, lab50); - } else if (l <= 100) { - // For L less than 100, scale from the base color to L=100 - rgb = interpolateRGB(PaletteRGBImpl.ramp(l), lab50, lab100); - } else { - // For L greater than 100, scale from L=100 to white - const percentFromLab100ToRgbMax = (l - 100.0) / lAbove; - rgb = interpolateRGB(percentFromLab100ToRgbMax, lab100, rgbMax); - } - - rgb = PaletteRGBImpl.saturationBump(lab50, rgb).roundToPrecision(4); - - swatches.push(SwatchRGB.from(rgb)); - } - - return new PaletteRGBImpl(source, swatches); - } - - /** - * Adjust one end of the contrast-based palette so it doesn't abruptly fall to black (or white). - * @param swatchContrast Function to get the target contrast for the next swatch - * @param referencePalette The high resolution palette - * @param targetPalette The contrast-based palette to adjust - * @param direction The end to adjust - */ - private static adjustEnd( - swatchContrast: (swatch: SwatchRGB) => number, - referencePalette: PaletteRGBImpl, - targetPalette: SwatchRGB[], - direction: 1 | -1, - ) { - // Careful with the use of referencePalette as only the refSwatches is reversed. - const refSwatches = direction === -1 ? referencePalette.swatches : referencePalette.reversedSwatches; - const refIndex = (swatch: SwatchRGB) => { - const index = referencePalette.closestIndexOf(swatch); - return direction === 1 ? referencePalette.lastIndex - index : index; - }; - - // Only operates on the 'end' end of the array, so flip if we're adjusting the 'beginning' - if (direction === 1) { - targetPalette.reverse(); - } - - const targetContrast = swatchContrast(targetPalette[targetPalette.length - 2]); - const actualContrast = roundToPrecisionSmall( - contrast(targetPalette[targetPalette.length - 1], targetPalette[targetPalette.length - 2]), - 2, - ); - if (actualContrast < targetContrast) { - // Remove last swatch if not sufficient contrast - targetPalette.pop(); - - // Distribute to the last swatch - const safeSecondSwatch = referencePalette.colorContrast( - refSwatches[referencePalette.lastIndex], - targetContrast, - undefined, - direction, - ); - const safeSecondRefIndex = refIndex(safeSecondSwatch); - const targetSwatchCurrentRefIndex = refIndex(targetPalette[targetPalette.length - 2]); - const swatchesToSpace = safeSecondRefIndex - targetSwatchCurrentRefIndex; - let space = 1; - for (let i = targetPalette.length - swatchesToSpace - 1; i < targetPalette.length; i++) { - const currentRefIndex = refIndex(targetPalette[i]); - const nextRefIndex = i === targetPalette.length - 1 ? referencePalette.lastIndex : currentRefIndex + space; - targetPalette[i] = refSwatches[nextRefIndex]; - space++; - } - } - - if (direction === 1) { - targetPalette.reverse(); - } - } - - /** - * Generate a palette with consistent minimum contrast between swatches. - * @param source The source color - * @param options Palette generation options - * @returns A palette meeting the requested contrast between swatches. - */ - private static createColorPaletteByContrast(source: SwatchRGB, options: PaletteRGBOptions): SwatchRGB[] { - const referencePalette = PaletteRGBImpl.createHighResolutionPalette(source); - - // Ramp function to increase contrast as the swatches get darker - const nextContrast = (swatch: SwatchRGB) => { - const c = options.stepContrast + options.stepContrast * (1 - swatch.relativeLuminance) * options.stepContrastRamp; - return roundToPrecisionSmall(c, 2); - }; - - const swatches: SwatchRGB[] = []; - - // Start with the source color or the light end color - let ref = options.preserveSource ? source : referencePalette.swatches[0]; - swatches.push(ref); - - // Add swatches with contrast toward dark - do { - const targetContrast = nextContrast(ref); - ref = referencePalette.colorContrast(ref, targetContrast, undefined, 1); - swatches.push(ref); - } while (ref.relativeLuminance > 0); - - // Add swatches with contrast toward light - if (options.preserveSource) { - ref = source; - do { - // This is off from the dark direction because `ref` here is the darker swatch, probably subtle - const targetContrast = nextContrast(ref); - ref = referencePalette.colorContrast(ref, targetContrast, undefined, -1); - swatches.unshift(ref); - } while (ref.relativeLuminance < 1); - } - - // Validate dark end - this.adjustEnd(nextContrast, referencePalette, swatches, -1); - - // Validate light end - if (options.preserveSource) { - this.adjustEnd(nextContrast, referencePalette, swatches, 1); - } - - return swatches; - } - - /** - * Create a color palette from a provided swatch - * @param source - The source swatch to create a palette from - * @returns - */ - static from(source: SwatchRGB, options?: Partial): PaletteRGB { - const opts = options === void 0 || null ? defaultPaletteRGBOptions : { ...defaultPaletteRGBOptions, ...options }; - - return new PaletteRGBImpl(source, Object.freeze(PaletteRGBImpl.createColorPaletteByContrast(source, opts))); - } -} diff --git a/packages/web-components/src/color/recipe.ts b/packages/web-components/src/color/recipe.ts deleted file mode 100644 index 76068c5e39560..0000000000000 --- a/packages/web-components/src/color/recipe.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Swatch } from './swatch'; - -/** @public */ -export interface InteractiveSwatchSet { - /** - * The swatch to apply to the rest state - */ - rest: Swatch; - - /** - * The swatch to apply to the hover state - */ - hover: Swatch; - - /** - * The swatch to apply to the active state - */ - active: Swatch; - - /** - * The swatch to apply to the focus state - */ - focus: Swatch; -} diff --git a/packages/web-components/src/color/recipes/contrast-and-delta-swatch-set.ts b/packages/web-components/src/color/recipes/contrast-and-delta-swatch-set.ts deleted file mode 100644 index 9125137a3b756..0000000000000 --- a/packages/web-components/src/color/recipes/contrast-and-delta-swatch-set.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Palette } from '../palette'; -import { InteractiveSwatchSet } from '../recipe'; -import { Swatch } from '../swatch'; -import { directionByIsDark } from '../utilities/direction-by-is-dark'; -import { isDark } from '../utilities/is-dark'; - -/** - * @internal - */ -export function contrastAndDeltaSwatchSet( - palette: Palette, - reference: Swatch, - baseContrast: number, - restDelta: number, - hoverDelta: number, - activeDelta: number, - focusDelta: number, - direction?: -1 | 1 | null, -): InteractiveSwatchSet { - if (direction === null || direction === void 0) { - direction = directionByIsDark(reference); - } - const baseIndex = palette.closestIndexOf(palette.colorContrast(reference, baseContrast)); - - return { - rest: palette.get(baseIndex + direction * restDelta), - hover: palette.get(baseIndex + direction * hoverDelta), - active: palette.get(baseIndex + direction * activeDelta), - focus: palette.get(baseIndex + direction * focusDelta), - }; -} - -/** - * @internal - */ -export function contrastAndDeltaSwatchSetByLuminance( - palette: Palette, - reference: Swatch, - lightBaseContrast: number, - lightRestDelta: number, - lightHoverDelta: number, - lightActiveDelta: number, - lightFocusDelta: number, - lightDirection: -1 | 1 | undefined | null = undefined, - darkBaseContrast: number, - darkRestDelta: number, - darkHoverDelta: number, - darkActiveDelta: number, - darkFocusDelta: number, - darkDirection: -1 | 1 | undefined | null = undefined, -): InteractiveSwatchSet { - if (isDark(reference)) { - return contrastAndDeltaSwatchSet( - palette, - reference, - darkBaseContrast, - darkRestDelta, - darkHoverDelta, - darkActiveDelta, - darkFocusDelta, - darkDirection, - ); - } else { - return contrastAndDeltaSwatchSet( - palette, - reference, - lightBaseContrast, - lightRestDelta, - lightHoverDelta, - lightActiveDelta, - lightFocusDelta, - lightDirection, - ); - } -} diff --git a/packages/web-components/src/color/recipes/contrast-swatch.spec.ts b/packages/web-components/src/color/recipes/contrast-swatch.spec.ts deleted file mode 100644 index 9f181636d4808..0000000000000 --- a/packages/web-components/src/color/recipes/contrast-swatch.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { expect } from 'chai'; -import { PaletteRGB } from '../palette'; -import { SwatchRGB } from '../swatch'; -import { accentBase, middleGrey } from '../utilities/color-constants'; -import { contrastSwatch } from './contrast-swatch'; - -describe('contrastSwatch', (): void => { - const neutralPalette = PaletteRGB.from(middleGrey); - const accentPalette = PaletteRGB.from(accentBase); - - neutralPalette.swatches.concat(accentPalette.swatches).forEach((swatch): void => { - it(`${swatch} should resolve a color from the neutral palette`, (): void => { - expect(neutralPalette.swatches.indexOf(contrastSwatch(neutralPalette, swatch, 4.5) as SwatchRGB)).not.to.equal( - -1, - ); - }); - }); - - neutralPalette.swatches.concat(accentPalette.swatches).forEach((swatch): void => { - it(`${swatch} should always be at least 4.5 : 1 against the background`, (): void => { - expect( - swatch.contrast(contrastSwatch(neutralPalette, swatch, 4.5)), - // Because contrastSwatch follows the direction patterns of neutralForeground, - // a backgroundColor #777777 is impossible to hit 4.5 against. - ).to.be.gte(swatch.toColorString().toUpperCase() === '#777777' ? 4.48 : 4.5); - expect(swatch.contrast(contrastSwatch(neutralPalette, swatch, 4.5))).to.be.lessThan(5); - }); - }); -}); diff --git a/packages/web-components/src/color/recipes/contrast-swatch.ts b/packages/web-components/src/color/recipes/contrast-swatch.ts deleted file mode 100644 index f1516024c8edd..0000000000000 --- a/packages/web-components/src/color/recipes/contrast-swatch.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Palette } from '../palette'; -import { Swatch } from '../swatch'; - -/** - * Color algorithm using contrast from the reference color. - * - * @param palette - The palette to operate on - * @param reference - The reference color - * @param contrast - The desired minimum contrast - * - * @internal - */ -export function contrastSwatch(palette: Palette, reference: Swatch, contrast: number): Swatch { - return palette.colorContrast(reference, contrast); -} diff --git a/packages/web-components/src/color/recipes/delta-swatch-set.ts b/packages/web-components/src/color/recipes/delta-swatch-set.ts deleted file mode 100644 index fc2f15ac63a54..0000000000000 --- a/packages/web-components/src/color/recipes/delta-swatch-set.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Palette } from '../palette'; -import { InteractiveSwatchSet } from '../recipe'; -import { Swatch } from '../swatch'; -import { directionByIsDark } from '../utilities/direction-by-is-dark'; -import { isDark } from '../utilities/is-dark'; - -/** - * Color algorithm using deltas from the reference color for states. - * - * @param palette The palette to operate on - * @param reference The reference color to calculate a color for - * @param restDelta The rest state offset from reference - * @param hoverDelta The hover state offset from reference - * @param activeDelta The active state offset from reference - * @param focusDelta The focus state offset from reference - * @param direction The direction the deltas move on the ramp, default goes darker for light references and lighter for dark references - * - * @internal - */ -export function deltaSwatchSet( - palette: Palette, - reference: Swatch, - restDelta: number, - hoverDelta: number, - activeDelta: number, - focusDelta: number, - direction?: -1 | 1 | null, -): InteractiveSwatchSet { - const referenceIndex = palette.closestIndexOf(reference); - if (direction === null || direction === void 0) { - direction = directionByIsDark(reference); - } - - return { - rest: palette.get(referenceIndex + direction * restDelta), - hover: palette.get(referenceIndex + direction * hoverDelta), - active: palette.get(referenceIndex + direction * activeDelta), - focus: palette.get(referenceIndex + direction * focusDelta), - }; -} - -/** - * Color algorithm using deltas from the reference color for states, allowing different deltas based on a light or dark reference color. - * - * @param palette The palette to operate on - * @param reference The reference color to calculate a color for - * @param lightRestDelta The rest offset for a light reference - * @param lightHoverDelta The hover offset for a light reference - * @param lightActiveDelta The rest offset for a light reference - * @param lightFocusDelta The hover offset for a light reference - * @param lightDirection The direction the deltas move on the ramp, default goes darker for light references - * @param darkRestDelta The rest offset for a dark reference - * @param darkHoverDelta The hover offset for a dark reference - * @param darkActiveDelta The rest offset for a dark reference - * @param darkFocusDelta The hover offset for a dark reference - * @param darkDirection The direction the deltas move on the ramp, default goes lighter for dark references - * - * @internal - */ -export function deltaSwatchSetByLuminance( - palette: Palette, - reference: Swatch, - lightRestDelta: number, - lightHoverDelta: number, - lightActiveDelta: number, - lightFocusDelta: number, - lightDirection: -1 | 1 | undefined | null = undefined, - darkRestDelta: number, - darkHoverDelta: number, - darkActiveDelta: number, - darkFocusDelta: number, - darkDirection: -1 | 1 | undefined | null = undefined, -): InteractiveSwatchSet { - if (isDark(reference)) { - return deltaSwatchSet( - palette, - reference, - darkRestDelta, - darkHoverDelta, - darkActiveDelta, - darkFocusDelta, - darkDirection, - ); - } else { - return deltaSwatchSet( - palette, - reference, - lightRestDelta, - lightHoverDelta, - lightActiveDelta, - lightFocusDelta, - lightDirection, - ); - } -} diff --git a/packages/web-components/src/color/recipes/delta-swatch.ts b/packages/web-components/src/color/recipes/delta-swatch.ts deleted file mode 100644 index 8cb14a4122cb8..0000000000000 --- a/packages/web-components/src/color/recipes/delta-swatch.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Swatch } from '../swatch'; -import { Palette } from '../palette'; -import { directionByIsDark } from '../utilities/direction-by-is-dark'; - -/** - * Color algorithm using a delta from the reference color. - * - * @param palette - The palette to operate on - * @param reference - The reference color - * @param delta - The offset from the reference - * - * @internal - */ -export function deltaSwatch(palette: Palette, reference: Swatch, delta: number): Swatch { - return palette.get(palette.closestIndexOf(reference) + directionByIsDark(reference) * delta); -} diff --git a/packages/web-components/src/color/recipes/focus-stroke.ts b/packages/web-components/src/color/recipes/focus-stroke.ts deleted file mode 100644 index d1b6e5871ea84..0000000000000 --- a/packages/web-components/src/color/recipes/focus-stroke.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Palette } from '../palette'; -import { Swatch } from '../swatch'; -import { black, white } from '../utilities/color-constants'; -import { isDark } from '../utilities/is-dark'; - -/** - * @internal - */ -export function focusStrokeOuter(palette: Palette, reference: Swatch) { - return isDark(reference) ? white : black; -} - -/** - * @internal - */ -export function focusStrokeInner(palette: Palette, reference: Swatch, focusColor: Swatch) { - return isDark(reference) ? black : white; -} diff --git a/packages/web-components/src/color/recipes/foreground-on-accent.spec.ts b/packages/web-components/src/color/recipes/foreground-on-accent.spec.ts deleted file mode 100644 index d0c7edd655eea..0000000000000 --- a/packages/web-components/src/color/recipes/foreground-on-accent.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { expect } from 'chai'; -import { SwatchRGB } from '../swatch'; -import { black } from '../utilities/color-constants'; -import { foregroundOnAccent } from './foreground-on-accent'; - -describe('Cut text', (): void => { - it('should return black when background does not meet contrast ratio', (): void => { - const small = foregroundOnAccent(SwatchRGB.create(1, 1, 1), 4.5) as SwatchRGB; - const large = foregroundOnAccent(SwatchRGB.create(1, 1, 1), 3) as SwatchRGB; - - expect(small.r).to.equal(black.r); - expect(small.g).to.equal(black.g); - expect(small.b).to.equal(black.b); - - expect(large.r).to.equal(black.r); - expect(large.g).to.equal(black.g); - expect(large.b).to.equal(black.b); - }); -}); diff --git a/packages/web-components/src/color/recipes/foreground-on-accent.ts b/packages/web-components/src/color/recipes/foreground-on-accent.ts deleted file mode 100644 index 61e12195472a1..0000000000000 --- a/packages/web-components/src/color/recipes/foreground-on-accent.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Swatch } from '../swatch'; -import { black, white } from '../utilities/color-constants'; - -/** - * @internal - */ -export function foregroundOnAccent(reference: Swatch, contrastTarget: number) { - return reference.contrast(white) >= contrastTarget ? white : black; -} - -export function foregroundOnAccentSet( - restFill: Swatch, - hoverFill: Swatch, - activeFill: Swatch, - focusFill: Swatch, - contrastTarget: number, -) { - const defaultRule = fill => (fill.contrast(white) >= contrastTarget ? white : black); - const restForeground = defaultRule(restFill); - const hoverForeground = defaultRule(hoverFill); - // Active doe not have contrast requirements, so if rest and hover use the same color, use that for active even if it would not have passed the contrast check. - const activeForeground = - restForeground.relativeLuminance === hoverForeground.relativeLuminance ? restForeground : defaultRule(activeFill); - const focusForeground = defaultRule(focusFill); - return { - rest: restForeground, - hover: hoverForeground, - active: activeForeground, - focus: focusForeground, - }; -} diff --git a/packages/web-components/src/color/recipes/gradient-shadow-stroke.ts b/packages/web-components/src/color/recipes/gradient-shadow-stroke.ts deleted file mode 100644 index 9084b08b0e6b3..0000000000000 --- a/packages/web-components/src/color/recipes/gradient-shadow-stroke.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { calculateOverlayColor, ColorRGBA64, computeAlphaBlend, parseColorHexRGB } from '@microsoft/fast-colors'; -import { Palette } from '../palette'; -import { InteractiveSwatchSet } from '../recipe'; -import { Swatch, SwatchRGB } from '../swatch'; -import { directionByIsDark } from '../utilities/direction-by-is-dark'; -import { GradientSwatchRGB } from './gradient-swatch'; - -const black = new ColorRGBA64(0, 0, 0); -const white = new ColorRGBA64(1, 1, 1); - -/** - * @internal - */ -export function gradientShadowStroke( - palette: Palette, - reference: Swatch, - restDelta: number, - hoverDelta: number, - activeDelta: number, - focusDelta: number, - shadowDelta: number, - direction?: -1 | 1, - shadowPercentage: number = 10, - blendWithReference: boolean = false, -): InteractiveSwatchSet { - const referenceIndex = palette.closestIndexOf(reference); - if (direction === void 0) { - direction = directionByIsDark(reference); - } - - function overlayHelper(color: Swatch): Swatch { - if (blendWithReference) { - const refIndex = palette.closestIndexOf(reference); - const refSwatch = palette.get(refIndex); - const overlaySolid = color.relativeLuminance < reference.relativeLuminance ? black : white; - const overlayColor = calculateOverlayColor( - parseColorHexRGB(color.toColorString())!, - parseColorHexRGB(refSwatch.toColorString())!, - overlaySolid, - ).roundToPrecision(2); - const blend = computeAlphaBlend(parseColorHexRGB(reference.toColorString())!, overlayColor); - return SwatchRGB.from(blend); - } else { - return color; - } - } - - const restIndex = referenceIndex + direction * restDelta; - const hoverIndex = restIndex + direction * (hoverDelta - restDelta); - const activeIndex = restIndex + direction * (activeDelta - restDelta); - const focusIndex = restIndex + direction * (focusDelta - restDelta); - - const startPosition = direction === -1 ? 0 : 100 - shadowPercentage; - const endPosition = direction === -1 ? shadowPercentage : 100; - - function gradientHelper(index: number, applyShadow: boolean): Swatch { - const color = palette.get(index); - if (applyShadow) { - // Shadow is actually "highlight" on top in dark mode. - const shadowColor = palette.get(index + direction! * shadowDelta); - const startColor = direction === -1 ? shadowColor : color; - const endColor = direction === -1 ? color : shadowColor; - const g = `linear-gradient(${overlayHelper(startColor).toColorString()} ${startPosition}%, ${overlayHelper( - endColor, - ).toColorString()} ${endPosition}%)`; - return GradientSwatchRGB.fromObject(startColor as SwatchRGB, g); - } else { - return overlayHelper(color); - } - } - - return { - rest: gradientHelper(restIndex, true), - hover: gradientHelper(hoverIndex, true), - active: gradientHelper(activeIndex, false), - focus: gradientHelper(focusIndex, true), - }; -} diff --git a/packages/web-components/src/color/recipes/gradient-swatch.ts b/packages/web-components/src/color/recipes/gradient-swatch.ts deleted file mode 100644 index 117a8e8f7ad53..0000000000000 --- a/packages/web-components/src/color/recipes/gradient-swatch.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { ColorRGBA64, rgbToRelativeLuminance } from '@microsoft/fast-colors'; -import { SwatchRGB } from '../swatch'; -import { contrast } from '../utilities/relative-luminance'; - -/** - * An implementation of {@link Swatch} that produces a gradient. - * This assumes a subtle gradient such that `relativeLuminance` is still meaningful, - * either with consistent luminance across the steps or a small edge of larger change. - * @internal - */ -export class GradientSwatchRGB implements SwatchRGB { - private color: ColorRGBA64; - private cssGradient: string; - - readonly relativeLuminance: number; - readonly r: number; - readonly g: number; - readonly b: number; - - /** - * - * @param red Red channel expressed as a number between 0 and 1 - * @param green Green channel expressed as a number between 0 and 1 - * @param blue Blue channel expressed as a number between 0 and 1 - */ - constructor(red: number, green: number, blue: number, cssGradient: string) { - this.color = new ColorRGBA64(red, green, blue); - this.cssGradient = cssGradient; - this.relativeLuminance = rgbToRelativeLuminance(this.color); - this.r = red; - this.g = green; - this.b = blue; - } - - public toColorString = () => this.cssGradient; - public contrast = contrast.bind(null, this); - public createCSS = this.toColorString; - - /** - * Creates a GradientSwatch from a base color and gradient definition - * @param obj The base color object, used for relative luminance - * @param cssGradient The actual gradient to be rendered - * @returns New GradientSwatch object - */ - static fromObject(obj: { r: number; g: number; b: number }, cssGradient: string) { - return new GradientSwatchRGB(obj.r, obj.g, obj.b, cssGradient); - } -} diff --git a/packages/web-components/src/color/recipes/neutral-layer-1.ts b/packages/web-components/src/color/recipes/neutral-layer-1.ts deleted file mode 100644 index ac1caf77c74ad..0000000000000 --- a/packages/web-components/src/color/recipes/neutral-layer-1.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Palette } from '../palette'; -import { Swatch } from '../swatch'; -import { baseLayerLuminanceSwatch } from '../utilities/base-layer-luminance'; - -/** - * @internal - */ -export function neutralLayer1Index(palette: Palette, baseLayerLuminance: number): number { - return palette.closestIndexOf(baseLayerLuminanceSwatch(baseLayerLuminance)); -} - -/** - * @internal - */ -export function neutralLayer1(palette: Palette, baseLayerLuminance: number): Swatch { - return palette.get(neutralLayer1Index(palette, baseLayerLuminance)); -} diff --git a/packages/web-components/src/color/recipes/neutral-layer-2.ts b/packages/web-components/src/color/recipes/neutral-layer-2.ts deleted file mode 100644 index e2efc5329cf45..0000000000000 --- a/packages/web-components/src/color/recipes/neutral-layer-2.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Palette } from '../palette'; -import { Swatch } from '../swatch'; -import { neutralLayer1Index } from './neutral-layer-1'; - -/** - * @internal - */ -export function neutralLayer2(palette: Palette, baseLayerLuminance: number, layerDelta: number): Swatch { - return palette.get(neutralLayer1Index(palette, baseLayerLuminance) + layerDelta * -1); -} diff --git a/packages/web-components/src/color/recipes/neutral-layer-3.ts b/packages/web-components/src/color/recipes/neutral-layer-3.ts deleted file mode 100644 index 3a179b57d7aa5..0000000000000 --- a/packages/web-components/src/color/recipes/neutral-layer-3.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Palette } from '../palette'; -import { Swatch } from '../swatch'; -import { neutralLayer1Index } from './neutral-layer-1'; - -/** - * @internal - */ -export function neutralLayer3(palette: Palette, baseLayerLuminance: number, layerDelta: number): Swatch { - return palette.get(neutralLayer1Index(palette, baseLayerLuminance) + layerDelta * -1 * 2); -} diff --git a/packages/web-components/src/color/recipes/neutral-layer-4.ts b/packages/web-components/src/color/recipes/neutral-layer-4.ts deleted file mode 100644 index 63365f19b178c..0000000000000 --- a/packages/web-components/src/color/recipes/neutral-layer-4.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Palette } from '../palette'; -import { Swatch } from '../swatch'; -import { neutralLayer1Index } from './neutral-layer-1'; - -/** - * @internal - */ -export function neutralLayer4(palette: Palette, baseLayerLuminance: number, layerDelta: number): Swatch { - return palette.get(neutralLayer1Index(palette, baseLayerLuminance) + layerDelta * -1 * 3); -} diff --git a/packages/web-components/src/color/recipes/neutral-layer-floating.ts b/packages/web-components/src/color/recipes/neutral-layer-floating.ts deleted file mode 100644 index a09a5addd1746..0000000000000 --- a/packages/web-components/src/color/recipes/neutral-layer-floating.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Palette } from '../palette'; -import { Swatch } from '../swatch'; -import { neutralLayer1Index } from './neutral-layer-1'; - -/** - * @internal - */ -export function neutralLayerFloating(palette: Palette, baseLayerLuminance: number, layerDelta: number): Swatch { - return palette.get(neutralLayer1Index(palette, baseLayerLuminance) + layerDelta); -} diff --git a/packages/web-components/src/color/recipes/neutral-layer.spec.ts b/packages/web-components/src/color/recipes/neutral-layer.spec.ts deleted file mode 100644 index b3516d9f11bdb..0000000000000 --- a/packages/web-components/src/color/recipes/neutral-layer.spec.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { expect } from 'chai'; -import { PaletteRGB } from '../palette'; -import { StandardLuminance } from '../utilities/base-layer-luminance'; -import { middleGrey } from '../utilities/color-constants'; -import { neutralLayerFloating } from './neutral-layer-floating'; -import { neutralLayer1 } from './neutral-layer-1'; -import { neutralLayer2 } from './neutral-layer-2'; -import { neutralLayer3 } from './neutral-layer-3'; -import { neutralLayer4 } from './neutral-layer-4'; -import { SwatchRGB } from '../swatch'; - -const neutralPalette = PaletteRGB.from(middleGrey); - -const enum NeutralPaletteLightModeOffsets { - L1 = 1, - L2 = 3, - L3 = 5, - L4 = 7, -} - -const enum NeutralPaletteDarkModeOffsets { - L1 = 47, - L2 = 49, - L3 = 51, - L4 = 52, -} - -describe('neutralLayer', (): void => { - describe('1', (): void => { - it('should return values from 1 when in light mode', (): void => { - expect(neutralLayer1(neutralPalette, StandardLuminance.LightMode).toColorString()).to.equal( - neutralPalette.get(NeutralPaletteLightModeOffsets.L1).toColorString(), - ); - }); - it('should return values from 1 when in dark mode', (): void => { - expect(neutralLayer1(neutralPalette, StandardLuminance.DarkMode).toColorString()).to.equal( - neutralPalette.get(NeutralPaletteDarkModeOffsets.L1).toColorString(), - ); - }); - }); - - describe('2', (): void => { - it('should return values from 2 when in light mode', (): void => { - expect(neutralLayer2(neutralPalette, StandardLuminance.LightMode, -2).toColorString()).to.equal( - neutralPalette.get(NeutralPaletteLightModeOffsets.L2).toColorString(), - ); - }); - it('should return values from 2 when in dark mode', (): void => { - expect(neutralLayer2(neutralPalette, StandardLuminance.DarkMode, -2).toColorString()).to.equal( - neutralPalette.get(NeutralPaletteDarkModeOffsets.L2).toColorString(), - ); - }); - }); - - describe('3', (): void => { - it('should return values from 3 when in light mode', (): void => { - expect(neutralLayer3(neutralPalette, StandardLuminance.LightMode, -2).toColorString()).to.equal( - neutralPalette.get(NeutralPaletteLightModeOffsets.L3).toColorString(), - ); - }); - it('should return values from 3 when in dark mode', (): void => { - expect(neutralLayer3(neutralPalette, StandardLuminance.DarkMode, -2).toColorString()).to.equal( - neutralPalette.get(NeutralPaletteDarkModeOffsets.L3).toColorString(), - ); - }); - }); - - describe('4', (): void => { - it('should return values from 4 when in light mode', (): void => { - expect(neutralLayer4(neutralPalette, StandardLuminance.LightMode, -2).toColorString()).to.equal( - neutralPalette.get(NeutralPaletteLightModeOffsets.L4).toColorString(), - ); - }); - it('should return values from 4 when in dark mode', (): void => { - expect(neutralLayer4(neutralPalette, StandardLuminance.DarkMode, -2).toColorString()).to.equal( - neutralPalette.get(NeutralPaletteDarkModeOffsets.L4).toColorString(), - ); - }); - }); - - describe('neutralLayerFloating', (): void => { - it('should return a color from the neutral palette', (): void => { - expect( - neutralPalette.swatches.includes( - neutralLayerFloating(neutralPalette, StandardLuminance.LightMode, -2) as SwatchRGB, - ), - ).to.be.true; - }); - }); -}); diff --git a/packages/web-components/src/color/recipes/underline-stroke.ts b/packages/web-components/src/color/recipes/underline-stroke.ts deleted file mode 100644 index b455ba64f9cce..0000000000000 --- a/packages/web-components/src/color/recipes/underline-stroke.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Palette } from '../palette'; -import { InteractiveSwatchSet } from '../recipe'; -import { Swatch, SwatchRGB } from '../swatch'; -import { directionByIsDark } from '../utilities/direction-by-is-dark'; -import { GradientSwatchRGB } from './gradient-swatch'; - -/** - * @internal - */ -export function underlineStroke( - palette: Palette, - reference: Swatch, - restDelta: number, - hoverDelta: number, - activeDelta: number, - focusDelta: number, - shadowDelta: number, - width: string, -): InteractiveSwatchSet { - const referenceIndex = palette.closestIndexOf(reference); - const direction = directionByIsDark(reference); - - const restIndex = referenceIndex + direction * restDelta; - const hoverIndex = restIndex + direction * (hoverDelta - restDelta); - const activeIndex = restIndex + direction * (activeDelta - restDelta); - const focusIndex = restIndex + direction * (focusDelta - restDelta); - - const midPosition = `calc(100% - ${width})`; - - function gradientHelper(index: number, applyShadow: boolean): Swatch { - const color = palette.get(index); - if (applyShadow) { - const underlineColor = palette.get(index + direction * shadowDelta); - const g = `linear-gradient(${color.toColorString()} ${midPosition}, ${underlineColor.toColorString()} ${midPosition}, ${underlineColor.toColorString()})`; - return GradientSwatchRGB.fromObject(color as SwatchRGB, g); - } else { - return color; - } - } - - return { - rest: gradientHelper(restIndex, true), - hover: gradientHelper(hoverIndex, true), - active: gradientHelper(activeIndex, false), - focus: gradientHelper(focusIndex, true), - }; -} diff --git a/packages/web-components/src/color/swatch.ts b/packages/web-components/src/color/swatch.ts deleted file mode 100644 index 34cfff6cefcaa..0000000000000 --- a/packages/web-components/src/color/swatch.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { ColorRGBA64, rgbToRelativeLuminance } from '@microsoft/fast-colors'; -import { contrast, RelativeLuminance } from './utilities/relative-luminance'; - -/** - * Represents a color in a {@link Palette} - * @public - */ -export interface Swatch extends RelativeLuminance { - toColorString(): string; - contrast(target: RelativeLuminance): number; -} - -/** @public */ -export interface SwatchRGB extends Swatch { - r: number; - g: number; - b: number; -} - -/** @public */ -export const SwatchRGB = Object.freeze({ - create(r: number, g: number, b: number): SwatchRGB { - return new SwatchRGBImpl(r, g, b); - }, - from(obj: { r: number; g: number; b: number }): SwatchRGB { - return new SwatchRGBImpl(obj.r, obj.g, obj.b); - }, -}); - -/** - * Runtime test for an objects conformance with the SwatchRGB interface. - * @internal - */ -export function isSwatchRGB(value: { [key: string]: any }): value is SwatchRGB { - const test: SwatchRGB = { - r: 0, - g: 0, - b: 0, - toColorString: () => '', - contrast: () => 0, - relativeLuminance: 0, - }; - - for (const key in test) { - if (typeof test[key] !== typeof value[key]) { - return false; - } - } - - return true; -} -/** - * An RGB implementation of {@link Swatch} - * @internal - */ -class SwatchRGBImpl extends ColorRGBA64 implements Swatch { - readonly relativeLuminance: number; - - /** - * - * @param red - Red channel expressed as a number between 0 and 1 - * @param green - Green channel expressed as a number between 0 and 1 - * @param blue - Blue channel expressed as a number between 0 and 1 - */ - constructor(red: number, green: number, blue: number) { - super(red, green, blue, 1); - this.relativeLuminance = rgbToRelativeLuminance(this); - } - - public toColorString = this.toStringHexRGB; - public contrast = contrast.bind(null, this); - public createCSS = this.toColorString; - - static fromObject(obj: { r: number; g: number; b: number }) { - return new SwatchRGBImpl(obj.r, obj.g, obj.b); - } -} diff --git a/packages/web-components/src/color/utilities/base-layer-luminance.ts b/packages/web-components/src/color/utilities/base-layer-luminance.ts deleted file mode 100644 index 19ab8bad5573b..0000000000000 --- a/packages/web-components/src/color/utilities/base-layer-luminance.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Swatch, SwatchRGB } from '../swatch'; - -export function baseLayerLuminanceSwatch(luminance: number): Swatch { - return SwatchRGB.create(luminance, luminance, luminance); -} - -/** - * Recommended values for light and dark mode for {@link @fluentui/web-components#baseLayerLuminance}. - * - * @public - */ -export enum StandardLuminance { - LightMode = 0.98, - DarkMode = 0.15, -} diff --git a/packages/web-components/src/color/utilities/binary-search.ts b/packages/web-components/src/color/utilities/binary-search.ts deleted file mode 100644 index 1cf193f15d231..0000000000000 --- a/packages/web-components/src/color/utilities/binary-search.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @internal - */ -export function binarySearch( - valuesToSearch: T[] | ReadonlyArray, - searchCondition: (value: T) => boolean, - startIndex: number = 0, - endIndex: number = valuesToSearch.length - 1, -): T { - if (endIndex === startIndex) { - return valuesToSearch[startIndex]; - } - - const middleIndex: number = Math.floor((endIndex - startIndex) / 2) + startIndex; - - // Check to see if this passes on the item in the center of the array - // if it does check the previous values - return searchCondition(valuesToSearch[middleIndex]) - ? binarySearch( - valuesToSearch, - searchCondition, - startIndex, - middleIndex, // include this index because it passed the search condition - ) - : binarySearch( - valuesToSearch, - searchCondition, - middleIndex + 1, // exclude this index because it failed the search condition - endIndex, - ); -} diff --git a/packages/web-components/src/color/utilities/color-constants.ts b/packages/web-components/src/color/utilities/color-constants.ts deleted file mode 100644 index 9e17f28aa9a05..0000000000000 --- a/packages/web-components/src/color/utilities/color-constants.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { parseColorHexRGB } from '@microsoft/fast-colors'; -import { SwatchRGB } from '../swatch'; - -/** - * @internal - */ -export const white = SwatchRGB.create(1, 1, 1); -/** - * @internal - */ -export const black = SwatchRGB.create(0, 0, 0); - -/** - * @internal - */ -export const middleGrey = SwatchRGB.create(0.5, 0.5, 0.5); - -/** - * @internal - */ - -const base = parseColorHexRGB('#0078D4')!; -export const accentBase = SwatchRGB.create(base.r, base.g, base.b); diff --git a/packages/web-components/src/color/utilities/direction-by-is-dark.ts b/packages/web-components/src/color/utilities/direction-by-is-dark.ts deleted file mode 100644 index 6c31b711d563e..0000000000000 --- a/packages/web-components/src/color/utilities/direction-by-is-dark.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Swatch } from '../swatch'; -import { isDark } from './is-dark'; - -/** - * @internal - */ -export function directionByIsDark(color: Swatch): 1 | -1 { - return isDark(color) ? -1 : 1; -} diff --git a/packages/web-components/src/color/utilities/is-dark.ts b/packages/web-components/src/color/utilities/is-dark.ts deleted file mode 100644 index 9a749dcaa237f..0000000000000 --- a/packages/web-components/src/color/utilities/is-dark.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Swatch } from '../swatch'; - -/* - * A color is in "dark" if there is more contrast between #000000 and a reference - * color than #FFFFFF and the reference color. That threshold can be expressed as a relative luminance - * using the contrast formula as (1 + 0.5) / (R + 0.05) === (R + 0.05) / (0 + 0.05), - * which reduces to the following, where 'R' is the relative luminance of the reference color - */ -const target = (-0.1 + Math.sqrt(0.21)) / 2; - -/** - * Determines if a color should be considered Dark Mode - * @param color - The color to check to mode of - * @returns boolean - * - * @internal - */ -export function isDark(color: Swatch): boolean { - return color.relativeLuminance <= target; -} diff --git a/packages/web-components/src/color/utilities/relative-luminance.ts b/packages/web-components/src/color/utilities/relative-luminance.ts deleted file mode 100644 index e530348e1ed29..0000000000000 --- a/packages/web-components/src/color/utilities/relative-luminance.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @public - */ -export interface RelativeLuminance { - /** - * A number between 0 and 1, calculated by {@link https://www.w3.org/WAI/GL/wiki/Relative_luminance} - */ - readonly relativeLuminance: number; -} - -/** - * @internal - */ -export function contrast(a: RelativeLuminance, b: RelativeLuminance): number { - const L1 = a.relativeLuminance > b.relativeLuminance ? a : b; - const L2 = a.relativeLuminance > b.relativeLuminance ? b : a; - - return (L1.relativeLuminance + 0.05) / (L2.relativeLuminance + 0.05); -} diff --git a/packages/web-components/src/combobox/combobox.stories.ts b/packages/web-components/src/combobox/combobox.stories.ts deleted file mode 100644 index 54288198241a5..0000000000000 --- a/packages/web-components/src/combobox/combobox.stories.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { fluentCombobox } from './index'; - -export default { - title: 'Components/Combobox', - component: fluentCombobox, - argTypes: { - appearance: { - options: ['filled', 'outline'], - control: { type: 'radio' }, - }, - disabled: { - control: { type: 'boolean' }, - }, - autocomplete: { - options: ['inline', 'list', 'none', 'both'], - control: { type: 'radio' }, - }, - position: { - options: ['above', 'below'], - control: { type: 'radio' }, - }, - required: { - control: { type: 'boolean' }, - }, - }, -}; - -const ComboboxTemplate = ({ appearance, disabled, autocomplete, position, required }) => ` - - - Please Please Me - With The Beatles - A Hard Day's Night - Beatles for Sale - Help! - Rubber Soul - Revolver - Sgt. Pepper's Lonely Hearts Club Band - Magical Mystery Tour - The Beatles - Yellow Submarine - Abbey Road - Let It Be - -`; - -export const Combobox = ComboboxTemplate.bind({}); - -Combobox.args = { - value: 'Christopher Eccleston', - appearance: 'outline', - disabled: false, -}; - -const example = ` - - Please Please Me - With The Beatles - A Hard Day's Night - Beatles for Sale - Help! - Rubber Soul - Revolver - Sgt. Pepper's Lonely Hearts Club Band - Magical Mystery Tour - The Beatles - Yellow Submarine - Abbey Road - Let It Be - -`; -Combobox.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/combobox/combobox.styles.ts b/packages/web-components/src/combobox/combobox.styles.ts deleted file mode 100644 index 6bf3c0fec6146..0000000000000 --- a/packages/web-components/src/combobox/combobox.styles.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { ComboboxOptions, disabledCursor, ElementDefinitionContext, forcedColorsStylesheetBehavior } from '@microsoft/fast-foundation'; -import { baseSelectStyles } from '../select/select.styles'; -import { appearanceBehavior } from '../utilities/behaviors'; -import { strokeWidth } from '../design-tokens'; -import { typeRampBase } from '../styles/patterns/type-ramp'; -import { inputFilledStyles, inputForcedColorStyles, inputOutlineStyles, inputStateStyles } from '../styles'; - -const logicalControlSelector: string = '.control'; -const interactivitySelector: string = ':not([disabled]):not([open])'; - -export const comboboxStyles: (context: ElementDefinitionContext, definition: ComboboxOptions) => ElementStyles = ( - context: ElementDefinitionContext, - definition: ComboboxOptions, -) => - css` - ${baseSelectStyles(context, definition)} - - ${inputStateStyles(context, definition, logicalControlSelector)} - - :host(:empty) .listbox { - display: none; - } - - :host([disabled]) *, - :host([disabled]) { - cursor: ${disabledCursor}; - user-select: none; - } - - :host(:active) .selected-value { - user-select: none; - } - - .selected-value { - -webkit-appearance: none; - background: transparent; - border: none; - color: inherit; - ${typeRampBase} - height: calc(100% - ${strokeWidth} * 1px)); - margin: auto 0; - width: 100%; - outline: none; - } - `.withBehaviors( - appearanceBehavior('outline', inputOutlineStyles(context, definition, logicalControlSelector, interactivitySelector)), - appearanceBehavior('filled', inputFilledStyles(context, definition, logicalControlSelector, interactivitySelector)), - forcedColorsStylesheetBehavior(inputForcedColorStyles(context, definition, logicalControlSelector, interactivitySelector)), - ); diff --git a/packages/web-components/src/combobox/combobox.vscode.definition.json b/packages/web-components/src/combobox/combobox.vscode.definition.json deleted file mode 100644 index 66ddaebb662e4..0000000000000 --- a/packages/web-components/src/combobox/combobox.vscode.definition.json +++ /dev/null @@ -1,121 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-combobox", - "title": "Combobox", - "description": "The Fluent UI combobox element", - "attributes": [ - { - "name": "appearance", - "title": "Appearance", - "description": "The combobox's visual treatment", - "type": "string", - "values": [ - { - "name": "filled" - }, - { - "name": "outline" - } - ], - "default": "outline", - "required": false - }, - { - "name": "autocomplete", - "title": "Autocomplete", - "description": "Sets the autocomplete method to use when the combobox receives user input", - "default": "", - "type": "string", - "values": [ - { - "name": "inline" - }, - { - "name": "list" - }, - { - "name": "both" - }, - { - "name": "none" - } - ] - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Sets the disabled state of the combobox", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "name", - "title": "Name", - "description": "This element's value will be surfaced during form submission under the provided name", - "type": "string", - "default": "", - "required": false - }, - { - "name": "position", - "title": "Position", - "description": "Controls the placement of the combobox dropdown", - "required": false, - "type": "string", - "values": [ - { - "name": "above" - }, - { - "name": "below" - } - ] - }, - { - "name": "placeholder", - "title": "Placeholder", - "description": "Sets the placeholder value of the combobox to provide a hint to the user", - "required": false, - "type": "string" - }, - { - "name": "value", - "title": "Value", - "description": "The initial value of the combobox", - "required": false, - "type": "string" - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "Supports fluent-option, option elements, or elements with a role of option" - }, - { - "name": "control", - "title": "Input Control slot", - "description": "Slot to replace the contents of the control container" - }, - { - "name": "indicator", - "title": "Indicator slot", - "description": "Slot to provide a custom icon to represent the visual indicator" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned before the contents of the control container" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the contents of the control container" - } - ] - } - ] -} diff --git a/packages/web-components/src/combobox/fixtures/base.html b/packages/web-components/src/combobox/fixtures/base.html deleted file mode 100644 index a464496211cb6..0000000000000 --- a/packages/web-components/src/combobox/fixtures/base.html +++ /dev/null @@ -1,267 +0,0 @@ -

Combobox

- -

Default

- - Please Please Me - With The Beatles - A Hard Day's Night - Beatles for Sale - Help! - Rubber Soul - Revolver - Sgt. Pepper's Lonely Hearts Club Band - Magical Mystery Tour - The Beatles - Yellow Submarine - Abbey Road - Let It Be - - -

Filled

- - Please Please Me - With The Beatles - A Hard Day's Night - Beatles for Sale - Help! - Rubber Soul - Revolver - Sgt. Pepper's Lonely Hearts Club Band - Magical Mystery Tour - The Beatles - Yellow Submarine - Abbey Road - Let It Be - - -

Default Selected

- - William Hartnell - Patrick Troughton - Jon Pertwee - Tom Baker - Peter Davidson - Colin Baker - Sylvester McCoy - Paul McGann - Christopher Eccleston - David Tenant - Matt Smith - Peter Capaldi - Jodie Whittaker - - -

Initial Value

- - William Hartnell - Patrick Troughton - Jon Pertwee - Tom Baker - Peter Davidson - Colin Baker - Sylvester McCoy - Paul McGann - Christopher Eccleston - David Tenant - Matt Smith - Peter Capaldi - Jodie Whittaker - - -

Combobox with Autocomplete

- -

Inline Autocomplete

- - William Hartnell - Patrick Troughton - Jon Pertwee - Tom Baker - Peter Davidson - Colin Baker - Sylvester McCoy - Paul McGann - Christopher Eccleston - David Tenant - Matt Smith - Peter Capaldi - Jodie Whittaker - - -

List Autocomplete

- - William Hartnell - Patrick Troughton - Jon Pertwee - Tom Baker - Peter Davidson - Colin Baker - Sylvester McCoy - Paul McGann - Christopher Eccleston - David Tenant - Matt Smith - Peter Capaldi - Jodie Whittaker - - -

Both Autocomplete

- - William Hartnell - Patrick Troughton - Jon Pertwee - Tom Baker - Peter Davidson - Colin Baker - Sylvester McCoy - Paul McGann - Christopher Eccleston - David Tenant - Matt Smith - Peter Capaldi - Jodie Whittaker - - -

Disabled Combobox

- - Extra Small - Small - Medium - Large - Extra Large - - -

Combobox with disabled items

- -

Combobox with alternating disabled items

- - Extra Small - Small - Medium - Large - Extra Large - - -

Combobox with adjacent disabled items at start of list

- - Extra Small - Small - Medium - Large - Extra Large - - -

Combobox with adjacent disabled items in middle of list

- - Extra Small - Small - Medium - Large - Extra Large - - -

Combobox with adjacent disabled items at end of list

- - Extra Small - Small - Medium - Large - Extra Large - - -

Combobox with all but one item disabled

- - Extra Small - Small - Medium - Large - Extra Large - - -

Combobox with all items disabled

- - Extra Small - Small - Medium - Large - Extra Large - - -

Combobox with placeholder

- - Extra Small - Small - Medium - Large - Extra Large - - -

Combobox with no items

- - -

Combobox with long list

- - Alabama - Alaska - Arizona - Arkansas - California - Colorado - Connecticut - Delaware - Florida - Georgia - Hawaii - Idaho - Illinois - Indiana - Iowa - Kansas - Kentucky - Louisiana - Maine - Maryland - Massachussets - Michigain - Minnesota - Mississippi - Missouri - Montana - Nebraska - Nevada - New Hampshire - New Jersey - New Mexico - New York - North Carolina - North Dakota - Ohio - Oklahoma - Oregon - Pennsylvania - Rhode Island - South Carolina - South Dakota - Texas - Tennessee - Utah - Vermont - Virginia - Washington - Wisconsin - West Virginia - Wyoming - - -

Forced positions

- -

Combobox with forced position above

- - Position forced above - Option Two - - -

Combobox with forced position below

- - Position forced below - Option Two - diff --git a/packages/web-components/src/combobox/index.ts b/packages/web-components/src/combobox/index.ts deleted file mode 100644 index 3129303d81a29..0000000000000 --- a/packages/web-components/src/combobox/index.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { attr } from '@microsoft/fast-element'; -import { - ComboboxOptions, - Combobox as FoundationCombobox, - comboboxTemplate as template, -} from '@microsoft/fast-foundation'; -import { fillColor, neutralLayerFloating } from '../design-tokens'; -import { comboboxStyles as styles } from './combobox.styles'; - -/** - * Combobox appearances - * @public - */ -export type ComboboxAppearance = 'filled' | 'outline'; - -/** - * The Fluent combobox class - * @internal - */ -export class Combobox extends FoundationCombobox { - /** - * The appearance of the element. - * - * @public - * @remarks - * HTML Attribute: appearance - */ - @attr({ mode: 'fromView' }) - public appearance: ComboboxAppearance; - - /** - * @internal - */ - public appearanceChanged(oldValue: ComboboxAppearance, newValue: ComboboxAppearance): void { - if (oldValue !== newValue) { - this.classList.add(newValue); - this.classList.remove(oldValue); - } - } - - /** - * @internal - */ - public connectedCallback(): void { - super.connectedCallback(); - - if (!this.appearance) { - this.appearance = 'outline'; - } - - if (this.listbox) { - fillColor.setValueFor(this.listbox, neutralLayerFloating); - } - } -} - -/** - * The Fluent Combobox Custom Element. Implements {@link @microsoft/fast-foundation#Combobox}, - * {@link @microsoft/fast-foundation#comboboxTemplate} - * - * @public - * @remarks - * HTML Element: \ - * - */ -export const fluentCombobox = Combobox.compose({ - baseName: 'combobox', - baseClass: FoundationCombobox, - shadowOptions: { - delegatesFocus: true, - }, - template, - styles, - indicator: ` - - - - `, -}); - -/** - * Styles for combobox - * @public - */ -export const comboboxStyles = styles; diff --git a/packages/web-components/src/component-definitions.js b/packages/web-components/src/component-definitions.js deleted file mode 100644 index 45c2de5d92a49..0000000000000 --- a/packages/web-components/src/component-definitions.js +++ /dev/null @@ -1,84 +0,0 @@ -import fluentAccordionItemDefinition from './accordion/accordion-item/accordion-item.vscode.definition.json'; -export { fluentAccordionItemDefinition }; -import fluentAccordionDefinition from './accordion/accordion.vscode.definition.json'; -export { fluentAccordionDefinition }; -import fluentAnchorDefinition from './anchor/anchor.vscode.definition.json'; -export { fluentAnchorDefinition }; -import fluentAnchoredRegionDefinition from './anchored-region/anchored-region.vscode.definition.json'; -export { fluentAnchoredRegionDefinition }; -import fluentBadgeDefinition from './badge/badge.vscode.definition.json'; -export { fluentBadgeDefinition }; -import fluentBreadcrumbDefinition from './breadcrumb/breadcrumb.vscode.definition.json'; -export { fluentBreadcrumbDefinition }; -import fluentBreadcrumbItemDefinition from './breadcrumb-item/breadcrumb-item.vscode.definition.json'; -export { fluentBreadcrumbItemDefinition }; -import fluentButtonDefinition from './button/button.vscode.definition.json'; -export { fluentButtonDefinition }; -import fluentCardDefinition from './card/card.vscode.definition.json'; -export { fluentCardDefinition }; -import fluentCheckboxDefinition from './checkbox/checkbox.vscode.definition.json'; -export { fluentCheckboxDefinition }; -import fluentComboboxDefinition from './combobox/combobox.vscode.definition.json'; -export { fluentComboboxDefinition }; -import fluentDataGridDefinition from './data-grid/data-grid.vscode.definition.json'; -export { fluentDataGridDefinition }; -import fluentDataGridCellDefinition from './data-grid/data-grid-cell.vscode.definition.json'; -export { fluentDataGridCellDefinition }; -import fluentDataGridRowDefinition from './data-grid/data-grid-row.vscode.definition.json'; -export { fluentDataGridRowDefinition }; -import fluentDesignSystemProviderDefinition from './design-system-provider/design-system-provider.vscode.definition.json'; -export { fluentDesignSystemProviderDefinition }; -import fluentDialogDefinition from './dialog/dialog.vscode.definition.json'; -export { fluentDialogDefinition }; -import fluentDividerDefinition from './divider/divider.vscode.definition.json'; -export { fluentDividerDefinition }; -import fluentFlipperDefinition from './flipper/flipper.vscode.definition.json'; -export { fluentFlipperDefinition }; -import fluentHorizontalScrollDefinition from './horizontal-scroll/horizontal-scroll.vscode.definition.json'; -export { fluentHorizontalScrollDefinition }; -import fluentListboxDefinition from './listbox/listbox.vscode.definition.json'; -export { fluentListboxDefinition }; -import fluentListboxOptionDefinition from './listbox-option/listbox-option.vscode.definition.json'; -export { fluentListboxOptionDefinition }; -import fluentMenuDefinition from './menu/menu.vscode.definition.json'; -export { fluentMenuDefinition }; -import fluentMenuItemDefinition from './menu-item/menu-item.vscode.definition.json'; -export { fluentMenuItemDefinition }; -import fluentNumberFieldDefinition from './number-field/number-field.vscode.definition.json'; -export { fluentNumberFieldDefinition }; -import fluentProgressRingDefinition from './progress/progress-ring/progress-ring.vscode.definition.json'; -export { fluentProgressRingDefinition }; -import fluentProgressDefinition from './progress/progress/progress.vscode.definition.json'; -export { fluentProgressDefinition }; -import fluentRadioDefinition from './radio/radio.vscode.definition.json'; -export { fluentRadioDefinition }; -import fluentRadioGroupDefinition from './radio-group/radio-group.vscode.definition.json'; -export { fluentRadioGroupDefinition }; -import fluentSearchDefinition from './search/search.vscode.definition.json'; -export { fluentSearchDefinition }; -import fluentSelectDefinition from './select/select.vscode.definition.json'; -export { fluentSelectDefinition }; -import fluentSkeletonDefinition from './skeleton/skeleton.vscode.definition.json'; -export { fluentSkeletonDefinition }; -import fluentSliderDefinition from './slider/slider.vscode.definition.json'; -export { fluentSliderDefinition }; -import fluentSliderLabelDefinition from './slider-label/slider-label.vscode.definition.json'; -export { fluentSliderLabelDefinition }; -import fluentSwitchDefinition from './switch/switch.vscode.definition.json'; -export { fluentSwitchDefinition }; -import fluentTabPanelDefinition from './tabs/tab-panel/tab-panel.vscode.definition.json'; -export { fluentTabPanelDefinition }; -import fluentTabDefinition from './tabs/tab/tab.vscode.definition.json'; -export { fluentTabDefinition }; -import fluentTabsDefinition from './tabs/tabs.vscode.definition.json'; -export { fluentTabsDefinition }; -import fluentTextAreaDefinition from './text-area/text-area.vscode.definition.json'; -export { fluentTextAreaDefinition }; -import fluentTextFieldDefinition from './text-field/text-field.vscode.definition.json'; -export { fluentTextFieldDefinition }; -import fluentTooltipDefinition from './tooltip/tooltip.vscode.definition.json'; -export { fluentTooltipDefinition }; -import fluentTreeItemDefinition from './tree-item/tree-item.vscode.definition.json'; -export { fluentTreeItemDefinition }; -import fluentTreeViewDefinition from './tree-view/tree-view.vscode.definition.json'; -export { fluentTreeViewDefinition }; diff --git a/packages/web-components/src/custom-elements.ts b/packages/web-components/src/custom-elements.ts deleted file mode 100644 index 687c7951093af..0000000000000 --- a/packages/web-components/src/custom-elements.ts +++ /dev/null @@ -1,198 +0,0 @@ -// These type imports are needed so that API-extractor doesn't add import types with improper pathing. -/* eslint-disable @typescript-eslint/no-unused-vars */ -import type { - Accordion, - AccordionItem, - Anchor, - AnchoredRegion, - Badge, - Breadcrumb, - BreadcrumbItem, - Button, - Calendar, - Card, - Checkbox, - Combobox, - DataGrid, - Dialog, - Divider, - Flipper, - HorizontalScroll, - Listbox, - ListboxOption, - Menu, - MenuItem, - NumberField, - Radio, - RadioGroup, - Search, - Select, - Skeleton, - Slider, - SliderLabel, - Switch, - Tabs, - TextArea, - TextField, - Toolbar, - Tooltip, - TreeItem, - TreeView, -} from '@microsoft/fast-foundation'; -/* eslint-disable @typescript-eslint/no-unused-vars */ - -/** - * Export all custom element definitions - */ -import type { Container } from '@microsoft/fast-foundation'; -import { fluentAccordion, fluentAccordionItem } from './accordion/index'; -import { fluentAnchor } from './anchor/index'; -import { fluentAnchoredRegion } from './anchored-region/index'; -import { fluentBadge } from './badge/index'; -import { fluentBreadcrumb } from './breadcrumb/index'; -import { fluentBreadcrumbItem } from './breadcrumb-item/index'; -import { fluentButton } from './button/index'; -import { fluentCalendar } from './calendar/index'; -import { fluentCard } from './card/index'; -import { fluentCheckbox } from './checkbox/index'; -import { fluentCombobox } from './combobox/index'; -import { fluentDataGrid, fluentDataGridCell, fluentDataGridRow } from './data-grid/index'; -import { fluentDesignSystemProvider } from './design-system-provider/index'; -import { fluentDialog } from './dialog/index'; -import { fluentDivider } from './divider/index'; -import { fluentFlipper } from './flipper/index'; -import { fluentHorizontalScroll } from './horizontal-scroll/index'; -import { fluentListbox } from './listbox/index'; -import { fluentOption } from './listbox-option/index'; -import { fluentMenu } from './menu/index'; -import { fluentMenuItem } from './menu-item/index'; -import { fluentNumberField } from './number-field/index'; -import { fluentProgress, fluentProgressRing } from './progress/index'; -import { fluentRadio } from './radio/index'; -import { fluentRadioGroup } from './radio-group/index'; -import { fluentSearch } from './search/index'; -import { fluentSelect } from './select/index'; -import { fluentSkeleton } from './skeleton/index'; -import { fluentSlider } from './slider/index'; -import { fluentSliderLabel } from './slider-label/index'; -import { fluentSwitch } from './switch/index'; -import { fluentTab, fluentTabPanel, fluentTabs } from './tabs/index'; -import { fluentTextArea } from './text-area/index'; -import { fluentTextField } from './text-field/index'; -import { fluentToolbar } from './toolbar/index'; -import { fluentTooltip } from './tooltip/index'; -import { fluentTreeView } from './tree-view/index'; -import { fluentTreeItem } from './tree-item/index'; - -export { - fluentAccordion, - fluentAccordionItem, - fluentAnchor, - fluentAnchoredRegion, - fluentBadge, - fluentBreadcrumb, - fluentBreadcrumbItem, - fluentButton, - fluentCard, - fluentCalendar, - fluentCheckbox, - fluentCombobox, - fluentDataGrid, - fluentDataGridCell, - fluentDataGridRow, - fluentDesignSystemProvider, - fluentDialog, - fluentDivider, - fluentFlipper, - fluentHorizontalScroll, - fluentListbox, - fluentOption, - fluentMenu, - fluentMenuItem, - fluentNumberField, - fluentProgress, - fluentProgressRing, - fluentRadio, - fluentRadioGroup, - fluentSearch, - fluentSelect, - fluentSkeleton, - fluentSlider, - fluentSliderLabel, - fluentSwitch, - fluentTabs, - fluentTab, - fluentTabPanel, - fluentTextArea, - fluentTextField, - fluentToolbar, - fluentTooltip, - fluentTreeView, - fluentTreeItem, -}; - -/** - * All Fluent UI Web Components - * @public - */ -export const allComponents = { - fluentAccordion, - fluentAccordionItem, - fluentAnchor, - fluentAnchoredRegion, - fluentBadge, - fluentBreadcrumb, - fluentBreadcrumbItem, - fluentButton, - fluentCalendar, - fluentCard, - fluentCheckbox, - fluentCombobox, - fluentDataGrid, - fluentDataGridCell, - fluentDataGridRow, - fluentDesignSystemProvider, - fluentDialog, - fluentDivider, - fluentFlipper, - fluentHorizontalScroll, - fluentListbox, - fluentOption, - fluentMenu, - fluentMenuItem, - fluentNumberField, - fluentProgress, - fluentProgressRing, - fluentRadio, - fluentRadioGroup, - fluentSearch, - fluentSelect, - fluentSkeleton, - fluentSlider, - fluentSliderLabel, - fluentSwitch, - fluentTabs, - fluentTab, - fluentTabPanel, - fluentTextArea, - fluentTextField, - fluentToolbar, - fluentTooltip, - fluentTreeView, - fluentTreeItem, - register(container?: Container, ...rest: any[]) { - if (!container) { - // preserve backward compatibility with code that loops through - // the values of this object and calls them as funcs with no args - return; - } - - for (const key in this) { - if (key === 'register') { - continue; - } - - this[key]().register(container, ...rest); - } - }, -}; diff --git a/packages/web-components/src/data-grid/data-grid-cell.styles.ts b/packages/web-components/src/data-grid/data-grid-cell.styles.ts deleted file mode 100644 index 7af16ffcfdcbb..0000000000000 --- a/packages/web-components/src/data-grid/data-grid-cell.styles.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { - ElementDefinitionContext, - focusVisible, - forcedColorsStylesheetBehavior, - FoundationElementDefinition, -} from '@microsoft/fast-foundation'; -import { - controlCornerRadius, - designUnit, - focusStrokeWidth, - neutralForegroundRest, - strokeWidth, -} from '../design-tokens'; -import { typeRampBase } from '../styles/patterns/type-ramp'; -import { focusTreatmentBase } from '../styles/focus'; - -export const dataGridCellStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - :host { - padding: calc((${designUnit} + ${focusStrokeWidth} - ${strokeWidth}) * 1px) calc(((${designUnit} * 3) + ${focusStrokeWidth} - ${strokeWidth}) * 1px); - color: ${neutralForegroundRest}; - box-sizing: border-box; - ${typeRampBase} - border: transparent calc(${strokeWidth} * 1px) solid; - overflow: hidden; - white-space: nowrap; - border-radius: calc(${controlCornerRadius} * 1px); - } - - :host(.column-header) { - font-weight: 600; - } - - :host(:${focusVisible}) { - ${focusTreatmentBase} - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host { - forced-color-adjust: none; - background: ${SystemColors.Field}; - color: ${SystemColors.FieldText}; - } - - :host(:${focusVisible}) { - outline-color: ${SystemColors.FieldText}; - } - `, - ), - ); diff --git a/packages/web-components/src/data-grid/data-grid-cell.vscode.definition.json b/packages/web-components/src/data-grid/data-grid-cell.vscode.definition.json deleted file mode 100644 index df7d52b505c6c..0000000000000 --- a/packages/web-components/src/data-grid/data-grid-cell.vscode.definition.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-data-grid-cell", - "title": "Data grid cell", - "description": "The Fluent UI data grid cell element", - "attributes": [ - { - "name": "cell-type", - "title": "Cell type", - "description": "The type of cell", - "type": "string", - "values": [{ "name": "default" }, { "name": "columnheader" }], - "required": false - }, - { - "name": "grid-column", - "title": "Grid column", - "description": "Positions the cell in the column layout.", - "type": "string", - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The cell content" - } - ] - } - ] -} diff --git a/packages/web-components/src/data-grid/data-grid-row.styles.ts b/packages/web-components/src/data-grid/data-grid-row.styles.ts deleted file mode 100644 index ddc7496a00b15..0000000000000 --- a/packages/web-components/src/data-grid/data-grid-row.styles.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - ElementDefinitionContext, - forcedColorsStylesheetBehavior, - FoundationElementDefinition, -} from '@microsoft/fast-foundation'; -import { fillColor, neutralStrokeDividerRest, strokeWidth } from '../design-tokens'; - -export const dataGridRowStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - :host { - display: grid; - padding: 1px 0; - box-sizing: border-box; - width: 100%; - border-bottom: calc(${strokeWidth} * 1px) solid ${neutralStrokeDividerRest}; - } - - :host(.header) { - } - - :host(.sticky-header) { - background: ${fillColor}; - position: sticky; - top: 0; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host { - } - `, - ), - ); diff --git a/packages/web-components/src/data-grid/data-grid-row.vscode.definition.json b/packages/web-components/src/data-grid/data-grid-row.vscode.definition.json deleted file mode 100644 index 3dd9274132623..0000000000000 --- a/packages/web-components/src/data-grid/data-grid-row.vscode.definition.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-data-grid-row", - "title": "Data grid row", - "description": "The Fluent UI data grid row element", - "attributes": [ - { - "name": "grid-template-columns", - "title": "Grid template columns", - "description": "Value that gets applied to the the css gridTemplateColumns attribute of child rows", - "type": "string", - "required": false - }, - { - "name": "row-type", - "title": "Row type", - "description": "The type of row", - "type": "string", - "values": [{ "name": "default" }, { "name": "header" }, { "name": "sticky-header" }], - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The row content as data grid cells" - } - ] - } - ] -} diff --git a/packages/web-components/src/data-grid/data-grid.stories.ts b/packages/web-components/src/data-grid/data-grid.stories.ts deleted file mode 100644 index 3e0f4a35e9031..0000000000000 --- a/packages/web-components/src/data-grid/data-grid.stories.ts +++ /dev/null @@ -1,452 +0,0 @@ -import { html } from '@microsoft/fast-element'; -import { Button, ColumnDefinition, DataGrid, DataGridCell, DataGridRow } from '@microsoft/fast-foundation'; -import { GenerateHeaderOptions } from '@microsoft/fast-foundation/dist/esm/data-grid/data-grid.options'; -import addons from '@storybook/addons'; -import { DOCS_RENDERED } from '@storybook/core-events'; -import DataGridTemplate from './fixtures/base.html'; -import './index'; - -/* eslint-disable @typescript-eslint/ban-types */ -let defaultGridElement: DataGrid | null = null; -const defaultRowData: object = newDataRow('default'); - -const columnWidths: string[] = ['1fr', '1fr', '1fr', '1fr']; - -const defaultRowItemTemplate = html` - -`; - -const customRowItemTemplate = html` - - -`; - -const customCellItemTemplate = html` - -`; - -const customHeaderCellItemTemplate = html` - -`; - -addons.getChannel().addListener(DOCS_RENDERED, (name: string) => { - if (name.toLowerCase().includes('data-grid')) { - defaultGridElement = document.getElementById('defaultGrid') as DataGrid; - reset(); - - const defaultGridRow = document.getElementById('defaultGridRow') as DataGridRow; - if (defaultGridRow) { - defaultGridRow.rowData = defaultRowData; - } - - const defaultRow = document.getElementById('defaultRow') as DataGridRow; - if (defaultRow) { - defaultRow.columnDefinitions = baseColumns; - defaultRow.rowData = defaultRowData; - } - - const defaultHeader = document.getElementById('defaultHeader') as DataGridRow; - if (defaultHeader) { - defaultHeader.columnDefinitions = baseColumns; - } - - const rowWithCellTemplate = document.getElementById('cellTemplateRow') as DataGridRow; - if (rowWithCellTemplate) { - rowWithCellTemplate.columnDefinitions = templateColumns; - rowWithCellTemplate.rowData = defaultRowData; - } - - const headerWithCellTemplate = document.getElementById('headerTemplateRow') as DataGridRow; - if (headerWithCellTemplate) { - headerWithCellTemplate.columnDefinitions = templateColumns; - } - - const defaultCell = document.getElementById('defaultCell') as DataGridCell; - if (defaultCell) { - defaultCell.columnDefinition = { columnDataKey: 'rowId' }; - defaultCell.rowData = defaultRowData; - } - - const headerCell = document.getElementById('headerCell') as DataGridCell; - if (headerCell) { - headerCell.columnDefinition = { - columnDataKey: 'name', - title: 'Components/Name', - }; - } - - const resetButton = document.getElementById('btnreset') as Button; - if (resetButton) { - resetButton.onclick = reset; - } - - const defaultColsButton = document.getElementById('btndefaultcols') as Button; - if (defaultColsButton) { - defaultColsButton.onclick = setDefaultCols; - } - - const templateColsButton = document.getElementById('btntemplatecols') as Button; - if (templateColsButton) { - templateColsButton.onclick = setTemplateCols; - } - - const addRowButton = document.getElementById('btnaddrow') as Button; - if (addRowButton) { - addRowButton.onclick = addRow; - } - - const removeRowButton = document.getElementById('btnremoverow') as Button; - if (removeRowButton) { - removeRowButton.onclick = removeRow; - } - - const noHeaderButton = document.getElementById('btnnoheader') as Button; - if (noHeaderButton) { - noHeaderButton.onclick = setNoHeader; - } - - const defaultHeaderButton = document.getElementById('btndefaultheader') as Button; - if (defaultHeaderButton) { - defaultHeaderButton.onclick = setDefaultHeader; - } - - const stickyHeaderButton = document.getElementById('btnstickyheader') as Button; - if (stickyHeaderButton) { - stickyHeaderButton.onclick = setStickyHeader; - } - - const defaultRowTemplateButton = document.getElementById('btndefaultrowtemplate') as Button; - if (defaultRowTemplateButton) { - defaultRowTemplateButton.onclick = setDefaultRowItemTemplate; - } - - const customRowTemplateButton = document.getElementById('btncustomrowtemplate') as Button; - if (customRowTemplateButton) { - customRowTemplateButton.onclick = setCustomRowItemTemplate; - } - - const defaultCellTemplateButton = document.getElementById('btndefaultcelltemplate') as Button; - if (defaultCellTemplateButton) { - defaultCellTemplateButton.onclick = setDefaultCellItemTemplate; - } - - const customCellTemplateButton = document.getElementById('btncustomcelltemplate') as Button; - if (customCellTemplateButton) { - customCellTemplateButton.onclick = setCustomCellItemTemplate; - } - - const defaultHeaderCellTemplateButton = document.getElementById('btndefaultheadercelltemplate') as Button; - if (defaultHeaderCellTemplateButton) { - defaultHeaderCellTemplateButton.onclick = setDefaultHeaderCellItemTemplate; - } - - const customHeaderCellTemplateButton = document.getElementById('btncustomheadercelltemplate') as Button; - if (customHeaderCellTemplateButton) { - customHeaderCellTemplateButton.onclick = setCustomHeaderCellItemTemplate; - } - - // note: we use mouse enter because clicking to move focus seems to confuse focus-visible - const focusLeftButton = document.getElementById('btnfocusleft') as Button; - if (focusLeftButton) { - focusLeftButton.onmouseenter = moveFocus; - } - - const focusRightButton = document.getElementById('btnfocusright') as Button; - if (focusRightButton) { - focusRightButton.onmouseenter = moveFocus; - } - - const focusUpButton = document.getElementById('btnfocusup') as Button; - if (focusUpButton) { - focusUpButton.onmouseenter = moveFocus; - } - - const focusDownButton = document.getElementById('btnfocusdown') as Button; - if (focusDownButton) { - focusDownButton.onmouseenter = moveFocus; - } - } -}); - -const buttonCellTemplate = html` - -`; - -const buttonHeaderCellTemplate = html` - -`; - -function reset(): void { - if (defaultGridElement === null) { - return; - } - defaultGridElement.columnDefinitions = null; - defaultGridElement.rowsData = newDataSet(10); -} - -function setDefaultCols(): void { - if (defaultGridElement === null) { - return; - } - defaultGridElement.columnDefinitions = baseColumns; -} - -function setTemplateCols(): void { - if (defaultGridElement === null) { - return; - } - defaultGridElement.columnDefinitions = templateColumns; -} - -function addRow(): void { - if (defaultGridElement === null || defaultGridElement.rowsData === null) { - return; - } - defaultGridElement.rowsData.push(newDataRow(`${defaultGridElement.rowsData.length + 1}`)); -} - -function removeRow(): void { - if (defaultGridElement === null || defaultGridElement.rowsData === null || defaultGridElement.rowsData.length === 0) { - return; - } - defaultGridElement.rowsData.pop(); -} - -function setNoHeader(): void { - if (defaultGridElement === null) { - return; - } - defaultGridElement.generateHeader = GenerateHeaderOptions.none; -} - -function setDefaultHeader(): void { - if (defaultGridElement === null) { - return; - } - defaultGridElement.generateHeader = GenerateHeaderOptions.default; -} - -function setDefaultRowItemTemplate(): void { - if (defaultGridElement === null) { - return; - } - defaultGridElement.rowItemTemplate = defaultRowItemTemplate; -} - -function setCustomRowItemTemplate(): void { - if (defaultGridElement === null) { - return; - } - defaultGridElement.rowItemTemplate = customRowItemTemplate; -} - -function setDefaultCellItemTemplate(): void { - if (defaultGridElement === null) { - return; - } - defaultGridElement.cellItemTemplate = undefined; -} - -function setCustomCellItemTemplate(): void { - if (defaultGridElement === null) { - return; - } - defaultGridElement.cellItemTemplate = customCellItemTemplate; -} - -function setDefaultHeaderCellItemTemplate(): void { - if (defaultGridElement === null) { - return; - } - defaultGridElement.headerCellItemTemplate = undefined; -} - -function setCustomHeaderCellItemTemplate(): void { - if (defaultGridElement === null) { - return; - } - defaultGridElement.headerCellItemTemplate = customHeaderCellItemTemplate; -} - -function moveFocus(e: MouseEvent): void { - if (defaultGridElement === null) { - return; - } - switch ((e.target as HTMLElement).id) { - case 'btnfocusleft': - defaultGridElement.focusColumnIndex = defaultGridElement.focusColumnIndex - 1; - break; - - case 'btnfocusright': - defaultGridElement.focusColumnIndex = defaultGridElement.focusColumnIndex + 1; - break; - - case 'btnfocusup': - defaultGridElement.focusRowIndex = defaultGridElement.focusRowIndex - 1; - break; - - case 'btnfocusdown': - defaultGridElement.focusRowIndex = defaultGridElement.focusRowIndex + 1; - break; - } -} - -function headerTemplateButtonClick(cell: DataGridCell): void { - if (cell.columnDefinition === null || defaultGridElement === null || defaultGridElement.columnDefinitions === null) { - return; - } - - const index: number = defaultGridElement.columnDefinitions.indexOf(cell.columnDefinition); - - if (columnWidths[index] === '1fr') { - columnWidths.splice(index, 1, '2fr'); - } else { - columnWidths.splice(index, 1, '1fr'); - } - - defaultGridElement.gridTemplateColumns = `${columnWidths[0]} ${columnWidths[1]} ${columnWidths[2]} ${columnWidths[3]}`; -} - -function cellTemplateButtonClick(cell: DataGridCell): void { - if (cell.columnDefinition === null || cell.rowData === null || defaultGridElement === null) { - return; - } - const newRowData: object = { ...cell.rowData }; - newRowData[cell.columnDefinition.columnDataKey] = 'clicked'; - - const rowIndex: number = defaultGridElement.rowsData.indexOf(cell.rowData); - - if (rowIndex > -1) { - defaultGridElement.rowsData.splice(rowIndex, 1, newRowData); - } -} - -function setStickyHeader(): void { - if (defaultGridElement === null) { - return; - } - defaultGridElement.generateHeader = GenerateHeaderOptions.sticky; -} - -function newDataSet(rowCount: number): object[] { - const newRows: object[] = []; - for (let i = 0; i <= rowCount; i++) { - newRows.push(newDataRow(`${i + 1}`)); - } - return newRows; -} - -function newDataRow(id: string): object { - return { - rowId: `rowid-${id}`, - item1: `value 1-${id}`, - item2: `value 2-${id}`, - item3: `value 3-${id}`, - item4: `value 4-${id}`, - item5: `value 5-${id}`, - item6: `value 6-${id}`, - }; -} - -const baseColumns: ColumnDefinition[] = [ - { columnDataKey: 'rowId' }, - { columnDataKey: 'item1' }, - { columnDataKey: 'item2' }, - { columnDataKey: 'item3' }, -]; - -const templateColumns: ColumnDefinition[] = [ - { - title: 'Components/RowID', - columnDataKey: 'rowId', - cellTemplate: buttonCellTemplate, - cellFocusTargetCallback: getFocusTarget, - headerCellTemplate: buttonHeaderCellTemplate, - headerCellFocusTargetCallback: getFocusTarget, - }, - { - title: 'Components/Column 1', - columnDataKey: 'item1', - cellTemplate: buttonCellTemplate, - cellFocusTargetCallback: getFocusTarget, - headerCellTemplate: buttonHeaderCellTemplate, - headerCellFocusTargetCallback: getFocusTarget, - }, - { - title: 'Components/Column 2', - columnDataKey: 'item2', - cellTemplate: buttonCellTemplate, - cellFocusTargetCallback: getFocusTarget, - headerCellTemplate: buttonHeaderCellTemplate, - headerCellFocusTargetCallback: getFocusTarget, - }, - { - title: 'Components/Column 3', - columnDataKey: 'item3', - cellTemplate: buttonCellTemplate, - cellFocusTargetCallback: getFocusTarget, - headerCellTemplate: buttonHeaderCellTemplate, - headerCellFocusTargetCallback: getFocusTarget, - }, -]; - -function getFocusTarget(cell: DataGridCell): HTMLElement { - return cell.querySelector('fast-button') as HTMLElement; -} - -/* eslint-enable @typescript-eslint/ban-types */ - -export default { - title: 'Components/Data Grid', -}; - -export const dataGrid = () => DataGridTemplate; - -const example = ` - -`; - -dataGrid.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/data-grid/data-grid.styles.ts b/packages/web-components/src/data-grid/data-grid.styles.ts deleted file mode 100644 index 29f27f52f386b..0000000000000 --- a/packages/web-components/src/data-grid/data-grid.styles.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { ElementDefinitionContext, FoundationElementDefinition } from '@microsoft/fast-foundation'; - -export const dataGridStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => css` - :host { - display: flex; - position: relative; - flex-direction: column; - } -`; diff --git a/packages/web-components/src/data-grid/data-grid.vscode.definition.json b/packages/web-components/src/data-grid/data-grid.vscode.definition.json deleted file mode 100644 index 9312776e38a9b..0000000000000 --- a/packages/web-components/src/data-grid/data-grid.vscode.definition.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-data-grid", - "title": "Data grid", - "description": "The Fluent UI data grid element", - "attributes": [ - { - "name": "generate-header", - "title": "Generate header", - "description": "Whether the grid should auto generate a header row", - "type": "string", - "values": [{ "name": "none" }, { "name": "default" }, { "name": "sticky" }], - "required": false - }, - { - "name": "grid-template-columns", - "title": "Grid template columns", - "description": "Value that gets applied to the the css gridTemplateColumns attribute of child rows", - "type": "string", - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content as data grid rows" - } - ] - } - ] -} diff --git a/packages/web-components/src/data-grid/fixtures/base.html b/packages/web-components/src/data-grid/fixtures/base.html deleted file mode 100644 index 6a229738aed33..0000000000000 --- a/packages/web-components/src/data-grid/fixtures/base.html +++ /dev/null @@ -1,55 +0,0 @@ - -

Data grid

- -

Default

- - - - -

Grid controls

- -
- Reset - Default columns - Template columns - - Add row - Remove row - - No header - Default header - Sticky header - - Default row item template - Custom row item template - - Default cell item template - Custom cell item template - Default header cell item template - Custom header cell item template -
- - -

Header

- - - -

Header with cell template

- - - -

Row

- - -

Row with cell template

- - -

Cell

- - -

Header cell

- diff --git a/packages/web-components/src/data-grid/index.ts b/packages/web-components/src/data-grid/index.ts deleted file mode 100644 index 557bbaa36f9ac..0000000000000 --- a/packages/web-components/src/data-grid/index.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { - DataGrid, - DataGridCell, - dataGridCellTemplate, - DataGridRow, - dataGridRowTemplate, - dataGridTemplate, -} from '@microsoft/fast-foundation'; -import { dataGridStyles as gridStyles } from './data-grid.styles'; -import { dataGridRowStyles as rowStyles } from './data-grid-row.styles'; -import { dataGridCellStyles as cellStyles } from './data-grid-cell.styles'; - -/** - * The Fluent Data Grid Cell Element. - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentDataGridCell = DataGridCell.compose({ - baseName: 'data-grid-cell', - template: dataGridCellTemplate, - styles: cellStyles, -}); - -/** - * Styles for DataGrid cell - * @public - */ -export const dataGridCellStyles = cellStyles; - -/** - * The Fluent Data Grid Row Element. - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentDataGridRow = DataGridRow.compose({ - baseName: 'data-grid-row', - template: dataGridRowTemplate, - styles: rowStyles, -}); - -/** - * Styles for DataGrid row - * @public - */ -export const dataGridRowStyles = rowStyles; - -/** - * The Fluent Data Grid Element. - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentDataGrid = DataGrid.compose({ - baseName: 'data-grid', - template: dataGridTemplate, - styles: gridStyles, -}); - -/** - * Styles for DataGrid - * @public - */ -export const dataGridStyles = gridStyles; - -/** - * Data grid base class definitions - * @public - */ -export { DataGrid, DataGridCell, DataGridRow }; diff --git a/packages/web-components/src/design-system-provider/design-system-provider.vscode.definition.json b/packages/web-components/src/design-system-provider/design-system-provider.vscode.definition.json deleted file mode 100644 index fdd896f8c3ea8..0000000000000 --- a/packages/web-components/src/design-system-provider/design-system-provider.vscode.definition.json +++ /dev/null @@ -1,510 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-design-system-provider", - "title": "Design System", - "description": "The Fluent UI design system provider element", - "attributes": [ - { - "name": "no-paint", - "title": "No paint", - "description": "Do not paint the background", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "fill-color", - "title": "Fill color", - "description": "The fill color used for backgrounds", - "type": "string", - "default": "#FFFFFF", - "required": false - }, - { - "name": "accent-base-color", - "title": "Accent base color", - "description": "The accent palette base color", - "type": "string", - "default": "#0078D4", - "required": false - }, - { - "name": "neutral-base-color", - "title": "Neutral base color", - "description": "The neutral palette base color", - "type": "string", - "default": "#808080", - "required": false - }, - { - "name": "density", - "title": "Density", - "description": "The density offset", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "design-unit", - "title": "Design unit", - "description": "UI dimension base unit", - "type": "number", - "default": 4, - "required": false - }, - { - "name": "direction", - "title": "Direction", - "description": "Support localized styles", - "type": "string", - "values": [ - { - "name": "ltr" - }, - { - "name": "rtl" - } - ], - "default": "ltr", - "required": false - }, - { - "name": "base-height-multiplier", - "title": "Base height multiplier", - "description": "Height multiplier at base density", - "type": "number", - "default": 8, - "required": false - }, - { - "name": "base-horizontal-spacing-multiplier", - "title": "Base horizontal spacing multiplier", - "description": "Horizontal spacing multiplier at the base density", - "type": "number", - "default": 3, - "required": false - }, - { - "name": "control-corner-radius", - "title": "Control Corner radius", - "description": "The corner radius value for control components", - "type": "number", - "default": 4, - "required": false - }, - { - "name": "layer-corner-radius", - "title": "Layer Corner radius", - "description": "The corner radius value for layer components", - "type": "number", - "default": 8, - "required": false - }, - { - "name": "stroke-width", - "title": "Stroke width", - "description": "The width of outline strokes", - "type": "number", - "default": 1, - "required": false - }, - { - "name": "focus-stroke-width", - "title": "Focus stroke width", - "description": "The width of focus outline strokes", - "type": "number", - "default": 2, - "required": false - }, - { - "name": "disabled-opacity", - "title": "Disabled opacity", - "description": "The disabled opacity for elements", - "type": "number", - "default": 0.3, - "required": false - }, - { - "name": "type-ramp-minus-2-font-size", - "title": "Font size (-2)", - "type": "string", - "default": "10px", - "required": false - }, - { - "name": "type-ramp-minus-2-line-height", - "title": "Line height (-2)", - "type": "string", - "default": "14px", - "required": false - }, - { - "name": "type-ramp-minus-1-font-size", - "title": "Font size (-1)", - "type": "string", - "default": "12px", - "required": false - }, - { - "name": "type-ramp-minus-1-line-height", - "title": "Line height (-1)", - "type": "string", - "default": "16px", - "required": false - }, - { - "name": "type-ramp-base-font-size", - "title": "Font size (base)", - "type": "string", - "default": "14px", - "required": false - }, - { - "name": "type-ramp-base-line-height", - "title": "Line height (base)", - "type": "string", - "default": "20px", - "required": false - }, - { - "name": "type-ramp-plus-1-font-size", - "title": "Font size (+1)", - "type": "string", - "default": "16px", - "required": false - }, - { - "name": "type-ramp-plus-1-line-height", - "title": "Line height (+1)", - "type": "string", - "default": "22px", - "required": false - }, - { - "name": "type-ramp-plus-2-font-size", - "title": "Font size (+2)", - "type": "string", - "default": "20px", - "required": false - }, - { - "name": "type-ramp-plus-2-line-height", - "title": "Line height (+2)", - "type": "string", - "default": "28px", - "required": false - }, - { - "name": "type-ramp-plus-3-font-size", - "title": "Font size (+3)", - "type": "string", - "default": "24px", - "required": false - }, - { - "name": "type-ramp-plus-3-line-height", - "title": "Line height (+3)", - "type": "string", - "default": "32px", - "required": false - }, - { - "name": "type-ramp-plus-4-font-size", - "title": "Font size (+4)", - "type": "string", - "default": "28px", - "required": false - }, - { - "name": "type-ramp-plus-4-line-height", - "title": "Line height (+4)", - "type": "string", - "default": "36px", - "required": false - }, - { - "name": "type-ramp-plus-5-font-size", - "title": "Font size (+5)", - "type": "string", - "default": "32px", - "required": false - }, - { - "name": "type-ramp-plus-5-line-height", - "title": "Line height (+5)", - "type": "string", - "default": "40px", - "required": false - }, - { - "name": "type-ramp-plus-6-font-size", - "title": "Font size (+6)", - "type": "string", - "default": "40px", - "required": false - }, - { - "name": "type-ramp-plus-6-line-height", - "title": "Line height (+6)", - "type": "string", - "default": "52px", - "required": false - }, - { - "name": "accent-fill-rest-delta", - "title": "Accent fill delta (rest)", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "accent-fill-hover-delta", - "title": "Accent fill delta (hover)", - "type": "number", - "default": 4, - "required": false - }, - { - "name": "accent-fill-active-delta", - "title": "Accent fill delta (active)", - "type": "number", - "default": -5, - "required": false - }, - { - "name": "accent-fill-focus-delta", - "title": "Accent fill delta (focus)", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "accent-foreground-rest-delta", - "title": "Accent foreground delta (rest)", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "accent-foreground-hover-delta", - "title": "Accent foreground delta (hover)", - "type": "number", - "default": 6, - "required": false - }, - { - "name": "accent-foreground-active-delta", - "title": "Accent foreground delta (active)", - "type": "number", - "default": -4, - "required": false - }, - { - "name": "accent-foreground-focus-delta", - "title": "Accent foreground delta (focus)", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "neutral-fill-rest-delta", - "title": "Neutral fill delta (rest)", - "type": "number", - "default": 7, - "required": false - }, - { - "name": "neutral-fill-hover-delta", - "title": "Neutral fill delta (hover)", - "type": "number", - "default": 10, - "required": false - }, - { - "name": "neutral-fill-active-delta", - "title": "Neutral fill delta (active)", - "type": "number", - "default": 5, - "required": false - }, - { - "name": "neutral-fill-focus-delta", - "title": "Neutral fill delta (focus)", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "neutral-fill-input-rest-delta", - "title": "Neutral fill input delta (rest)", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "neutral-fill-input-hover-delta", - "title": "Neutral fill input delta (hover)", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "neutral-fill-input-active-delta", - "title": "Neutral fill input delta (active)", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "neutral-fill-input-focus-delta", - "title": "Neutral fill input delta (focus)", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "neutral-fill-stealth-rest-delta", - "title": "Neutral fill stealth delta (rest)", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "neutral-fill-stealth-hover-delta", - "title": "Neutral fill stealth delta (hover)", - "type": "number", - "default": 5, - "required": false - }, - { - "name": "neutral-fill-stealth-active-delta", - "title": "Neutral fill stealth delta (active)", - "type": "number", - "default": 3, - "required": false - }, - { - "name": "neutral-fill-stealth-focus-delta", - "title": "Neutral fill stealth delta (focus)", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "neutral-fill-strong-hover-delta", - "title": "Neutral fill strong delta (hover)", - "type": "number", - "default": 8, - "required": false - }, - { - "name": "neutral-fill-strong-active-delta", - "title": "Neutral fill strong delta (active)", - "type": "number", - "default": -5, - "required": false - }, - { - "name": "neutral-fill-strong-focus-delta", - "title": "Neutral fill strong delta (focus)", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "neutral-fill-strong-rest-delta", - "title": "Neutral fill strong delta (rest)", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "base-layer-luminance", - "title": "Base layer luminance", - "description": "When set to a number between 0 and 1, this values controls the output of layer and card recipes", - "type": "number", - "default": 0.98, - "required": false - }, - { - "name": "neutral-fill-layer-rest-delta", - "title": "Layer background delta", - "type": "number", - "default": 3, - "required": false - }, - { - "name": "neutral-stroke-divider-rest-delta", - "title": "Neutral divider stroke delta", - "type": "number", - "default": 8, - "required": false - }, - { - "name": "neutral-stroke-rest-delta", - "title": "Neutral stroke delta (rest)", - "type": "number", - "default": 25, - "required": false - }, - { - "name": "neutral-stroke-hover-delta", - "title": "Neutral stroke delta (hover)", - "type": "number", - "default": 40, - "required": false - }, - { - "name": "neutral-stroke-active-delta", - "title": "Neutral stroke delta (active)", - "type": "number", - "default": 16, - "required": false - }, - { - "name": "neutral-stroke-focus-delta", - "title": "Neutral stroke delta (focus)", - "type": "number", - "default": 25, - "required": false - }, - { - "name": "neutral-contrast-fill-rest-delta", - "title": "Neutral contrast fill delta (rest)", - "type": "number", - "default": 0, - "required": false - }, - { - "name": "neutral-contrast-fill-hover-delta", - "title": "Neutral contrast fill delta (hover)", - "type": "number", - "default": -3, - "required": false - }, - { - "name": "neutral-contrast-fill-active-delta", - "title": "Neutral contrast fill delta (active)", - "type": "number", - "default": 7, - "required": false - }, - { - "name": "neutral-contrast-fill-focus-delta", - "title": "Neutral contrast fill delta (focus)", - "type": "number", - "default": 0, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot" - } - ] - } - ] -} diff --git a/packages/web-components/src/design-system-provider/index.ts b/packages/web-components/src/design-system-provider/index.ts deleted file mode 100644 index 53e258a053a9d..0000000000000 --- a/packages/web-components/src/design-system-provider/index.ts +++ /dev/null @@ -1,1079 +0,0 @@ -import { parseColorHexRGB } from '@microsoft/fast-colors'; -import { attr, css, html, nullableNumberConverter, Observable, ValueConverter } from '@microsoft/fast-element'; -import { - DesignToken, - DesignTokenValue, - display, - forcedColorsStylesheetBehavior, - FoundationElement, -} from '@microsoft/fast-foundation'; -import { Direction, SystemColors } from '@microsoft/fast-web-utilities'; -import { Swatch, SwatchRGB } from '../color/swatch'; -import { - accentBaseColor, - accentFillActiveDelta, - accentFillFocusDelta, - accentFillHoverDelta, - accentFillRestDelta, - accentForegroundActiveDelta, - accentForegroundFocusDelta, - accentForegroundHoverDelta, - accentForegroundRestDelta, - baseHeightMultiplier, - baseHorizontalSpacingMultiplier, - baseLayerLuminance, - controlCornerRadius, - density, - designUnit, - direction, - disabledOpacity, - fillColor, - focusStrokeWidth, - layerCornerRadius, - neutralBaseColor, - neutralFillActiveDelta, - neutralFillFocusDelta, - neutralFillHoverDelta, - neutralFillInputActiveDelta, - neutralFillInputFocusDelta, - neutralFillInputHoverDelta, - neutralFillInputRestDelta, - neutralFillLayerRestDelta, - neutralFillRestDelta, - neutralFillStealthActiveDelta, - neutralFillStealthFocusDelta, - neutralFillStealthHoverDelta, - neutralFillStealthRestDelta, - neutralFillStrongActiveDelta, - neutralFillStrongFocusDelta, - neutralFillStrongHoverDelta, - neutralForegroundRest, - neutralStrokeActiveDelta, - neutralStrokeDividerRestDelta, - neutralStrokeFocusDelta, - neutralStrokeHoverDelta, - neutralStrokeRestDelta, - strokeWidth, - typeRampBaseFontSize, - typeRampBaseLineHeight, - typeRampMinus1FontSize, - typeRampMinus1LineHeight, - typeRampMinus2FontSize, - typeRampMinus2LineHeight, - typeRampPlus1FontSize, - typeRampPlus1LineHeight, - typeRampPlus2FontSize, - typeRampPlus2LineHeight, - typeRampPlus3FontSize, - typeRampPlus3LineHeight, - typeRampPlus4FontSize, - typeRampPlus4LineHeight, - typeRampPlus5FontSize, - typeRampPlus5LineHeight, - typeRampPlus6FontSize, - typeRampPlus6LineHeight, -} from '../design-tokens'; - -/** - * A {@link ValueConverter} that converts to and from `Swatch` values. - * @remarks - * This converter allows for colors represented as string hex values, returning `null` if the - * input was `null` or `undefined`. - * @internal - */ -const swatchConverter: ValueConverter = { - toView(value: any): string | null { - if (value === null || value === undefined) { - return null; - } - return (value as Swatch)?.toColorString(); - }, - - fromView(value: any): any { - if (value === null || value === undefined) { - return null; - } - const color = parseColorHexRGB(value); - return color ? SwatchRGB.create(color!.r, color!.g, color!.b) : null; - }, -}; - -const backgroundStyles = css` - :host { - background-color: ${fillColor}; - color: ${neutralForegroundRest}; - } -`.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host { - background-color: ${SystemColors.Canvas}; - box-shadow: 0 0 0 1px ${SystemColors.CanvasText}; - color: ${SystemColors.CanvasText}; - } - `, - ), -); - -function designToken(token: DesignToken) { - return (source: DesignSystemProvider, key: string) => { - source[key + 'Changed'] = function (this: DesignSystemProvider, prev: T | undefined, next: T | undefined) { - if (next !== undefined && next !== null) { - token.setValueFor(this, next as DesignTokenValue); - } else { - token.deleteValueFor(this); - } - }; - }; -} - -/** - * The Fluent DesignSystemProvider Element. - * @public - */ -export class DesignSystemProvider extends FoundationElement { - constructor() { - super(); - - // If fillColor or baseLayerLuminance change, we need to - // re-evaluate whether we should have paint styles applied - const subscriber = { - handleChange: this.noPaintChanged.bind(this), - }; - Observable.getNotifier(this).subscribe(subscriber, 'fillColor'); - Observable.getNotifier(this).subscribe(subscriber, 'baseLayerLuminance'); - } - - public connectedCallback(): void { - super.connectedCallback(); - - this.noPaintChanged(); - } - - /** - * Used to instruct the FluentDesignSystemProvider - * that it should not set the CSS - * background-color and color properties - * - * @remarks - * HTML boolean attribute: no-paint - */ - @attr({ attribute: 'no-paint', mode: 'boolean' }) - public noPaint = false; - private noPaintChanged() { - if (!this.noPaint && (this.fillColor !== void 0 || this.baseLayerLuminance)) { - this.$fastController.addStyles(backgroundStyles); - } else { - this.$fastController.removeStyles(backgroundStyles); - } - } - - /** - * Define design system property attributes - * @remarks - * HTML attribute: fill-color - * - * CSS custom property: --fill-color - */ - @attr({ - attribute: 'fill-color', - converter: swatchConverter, - mode: 'fromView', - }) - @designToken(fillColor) - public fillColor: Swatch; - - /** - * A convenience to recreate the accentPalette - * @remarks - * HTML attribute: accent-base-color - */ - @attr({ - attribute: 'accent-base-color', - converter: swatchConverter, - mode: 'fromView', - }) - @designToken(accentBaseColor) - public accentBaseColor: Swatch; - - /** - * A convenience to recreate the neutralPalette - * @remarks - * HTML attribute: neutral-base-color - */ - @attr({ - attribute: 'neutral-base-color', - converter: swatchConverter, - mode: 'fromView', - }) - @designToken(neutralBaseColor) - public neutralBaseColor: Swatch; - - /** - * - * The density offset, used with designUnit to calculate height and spacing. - * - * @remarks - * HTML attribute: density - * - * CSS custom property: --density - */ - @attr({ - converter: nullableNumberConverter, - }) - @designToken(density) - public density: number; - - /** - * The grid-unit that UI dimensions are derived from in pixels. - * - * @remarks - * HTML attribute: design-unit - * - * CSS custom property: --design-unit - */ - @attr({ - attribute: 'design-unit', - converter: nullableNumberConverter, - }) - @designToken(designUnit) - public designUnit: number; - - /** - * The primary document direction. - * - * @remarks - * HTML attribute: direction - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'direction', - }) - @designToken(direction) - public direction: Direction; - - /** - * The number of designUnits used for component height at the base density. - * - * @remarks - * HTML attribute: base-height-multiplier - * - * CSS custom property: --base-height-multiplier - */ - @attr({ - attribute: 'base-height-multiplier', - converter: nullableNumberConverter, - }) - @designToken(baseHeightMultiplier) - public baseHeightMultiplier: number; - - /** - * The number of designUnits used for horizontal spacing at the base density. - * - * @remarks - * HTML attribute: base-horizontal-spacing-multiplier - * - * CSS custom property: --base-horizontal-spacing-multiplier - */ - @attr({ - attribute: 'base-horizontal-spacing-multiplier', - converter: nullableNumberConverter, - }) - @designToken(baseHorizontalSpacingMultiplier) - public baseHorizontalSpacingMultiplier: number; - - /** - * The corner radius applied to controls. - * - * @remarks - * HTML attribute: control-corner-radius - * - * CSS custom property: --control-corner-radius - */ - @attr({ - attribute: 'control-corner-radius', - converter: nullableNumberConverter, - }) - @designToken(controlCornerRadius) - public controlCornerRadius: number; - - /** - * The corner radius applied to layers. - * - * @remarks - * HTML attribute: layer-corner-radius - * - * CSS custom property: --layer-corner-radius - */ - @attr({ - attribute: 'layer-corner-radius', - converter: nullableNumberConverter, - }) - @designToken(layerCornerRadius) - public layerCornerRadius: number; - - /** - * The width of the standard stroke applied to stroke components in pixels. - * - * @remarks - * HTML attribute: stroke-width - * - * CSS custom property: --stroke-width - */ - @attr({ - attribute: 'stroke-width', - converter: nullableNumberConverter, - }) - @designToken(strokeWidth) - public strokeWidth: number; - - /** - * The width of the standard focus stroke in pixels. - * - * @remarks - * HTML attribute: focus-stroke-width - * - * CSS custom property: --focus-stroke-width - */ - @attr({ - attribute: 'focus-stroke-width', - converter: nullableNumberConverter, - }) - @designToken(focusStrokeWidth) - public focusStrokeWidth: number; - - /** - * The opacity of a disabled control. - * - * @remarks - * HTML attribute: disabled-opacity - * - * CSS custom property: --disabled-opacity - */ - @attr({ - attribute: 'disabled-opacity', - converter: nullableNumberConverter, - }) - @designToken(disabledOpacity) - public disabledOpacity: number; - - /** - * The font-size two steps below the base font-size - * - * @remarks - * HTML attribute: type-ramp-minus-2-font-size - * - * CSS custom property: --type-ramp-minus-2-font-size - */ - @attr({ - attribute: 'type-ramp-minus-2-font-size', - }) - @designToken(typeRampMinus2FontSize) - public typeRampMinus2FontSize: string; - - /** - * The line-height two steps below the base line-height - * - * @remarks - * HTML attribute: type-ramp-minus-2-line-height - * - * CSS custom property: --type-ramp-minus-2-line-height - */ - @attr({ - attribute: 'type-ramp-minus-2-line-height', - }) - @designToken(typeRampMinus2LineHeight) - public typeRampMinus2LineHeight: string; - - /** - * The font-size one step below the base font-size - * - * @remarks - * HTML attribute: type-ramp-minus-1-font-size - * - * CSS custom property: --type-ramp-minus-1-font-size - */ - @attr({ - attribute: 'type-ramp-minus-1-font-size', - }) - @designToken(typeRampMinus1FontSize) - public typeRampMinus1FontSize: string; - - /** - * The line-height one step below the base line-height - * - * @remarks - * HTML attribute: type-ramp-minus-1-line-height - * - * CSS custom property: --type-ramp-minus-1-line-height - */ - @attr({ - attribute: 'type-ramp-minus-1-line-height', - }) - @designToken(typeRampMinus1LineHeight) - public typeRampMinus1LineHeight: string; - - /** - * The base font-size of the relative type-ramp scale - * - * @remarks - * HTML attribute: type-ramp-base-font-size - * - * CSS custom property: --type-ramp-base-font-size - */ - @attr({ - attribute: 'type-ramp-base-font-size', - }) - @designToken(typeRampBaseFontSize) - public typeRampBaseFontSize: string; - - /** - * The base line-height of the relative type-ramp scale - * - * @remarks - * HTML attribute: type-ramp-base-line-height - * - * CSS custom property: --type-ramp-base-line-height - */ - @attr({ - attribute: 'type-ramp-base-line-height', - }) - @designToken(typeRampBaseLineHeight) - public typeRampBaseLineHeight: string; - - /** - * The font-size one step above the base font-size - * - * @remarks - * HTML attribute: type-ramp-plus-1-font-size - * - * CSS custom property: --type-ramp-plus-1-font-size - */ - @attr({ - attribute: 'type-ramp-plus-1-font-size', - }) - @designToken(typeRampPlus1FontSize) - public typeRampPlus1FontSize: string; - - /** - * The line-height one step above the base line-height - * - * @remarks - * HTML attribute: type-ramp-plus-1-line-height - * - * CSS custom property: --type-ramp-plus-1-line-height - */ - @attr({ - attribute: 'type-ramp-plus-1-line-height', - }) - @designToken(typeRampPlus1LineHeight) - public typeRampPlus1LineHeight: string; - - /** - * The font-size two steps above the base font-size - * - * @remarks - * HTML attribute: type-ramp-plus-2-font-size - * - * CSS custom property: --type-ramp-plus-2-font-size - */ - @attr({ - attribute: 'type-ramp-plus-2-font-size', - }) - @designToken(typeRampPlus2FontSize) - public typeRampPlus2FontSize: string; - - /** - * The line-height two steps above the base line-height - * - * @remarks - * HTML attribute: type-ramp-plus-2-line-height - * - * CSS custom property: --type-ramp-plus-2-line-height - */ - @attr({ - attribute: 'type-ramp-plus-2-line-height', - }) - @designToken(typeRampPlus2LineHeight) - public typeRampPlus2LineHeight: string; - - /** - * The font-size three steps above the base font-size - * - * @remarks - * HTML attribute: type-ramp-plus-3-font-size - * - * CSS custom property: --type-ramp-plus-3-font-size - */ - @attr({ - attribute: 'type-ramp-plus-3-font-size', - }) - @designToken(typeRampPlus3FontSize) - public typeRampPlus3FontSize: string; - - /** - * The line-height three steps above the base line-height - * - * @remarks - * HTML attribute: type-ramp-plus-3-line-height - * - * CSS custom property: --type-ramp-plus-3-line-height - */ - @attr({ - attribute: 'type-ramp-plus-3-line-height', - }) - @designToken(typeRampPlus3LineHeight) - public typeRampPlus3LineHeight: string; - - /** - * The font-size four steps above the base font-size - * - * @remarks - * HTML attribute: type-ramp-plus-4-font-size - * - * CSS custom property: --type-ramp-plus-4-font-size - */ - @attr({ - attribute: 'type-ramp-plus-4-font-size', - }) - @designToken(typeRampPlus4FontSize) - public typeRampPlus4FontSize: string; - - /** - * The line-height four steps above the base line-height - * - * @remarks - * HTML attribute: type-ramp-plus-4-line-height - * - * CSS custom property: --type-ramp-plus-4-line-height - */ - @attr({ - attribute: 'type-ramp-plus-4-line-height', - }) - @designToken(typeRampPlus4LineHeight) - public typeRampPlus4LineHeight: string; - - /** - * The font-size five steps above the base font-size - * - * @remarks - * HTML attribute: type-ramp-plus-5-font-size - * - * CSS custom property: --type-ramp-plus-5-font-size - */ - @attr({ - attribute: 'type-ramp-plus-5-font-size', - }) - @designToken(typeRampPlus5FontSize) - public typeRampPlus5FontSize: string; - - /** - * The line-height five steps above the base line-height - * - * @remarks - * HTML attribute: type-ramp-plus-5-line-height - * - * CSS custom property: --type-ramp-plus-5-line-height - */ - @attr({ - attribute: 'type-ramp-plus-5-line-height', - }) - @designToken(typeRampPlus5LineHeight) - public typeRampPlus5LineHeight: string; - - /** - * The font-size six steps above the base font-size - * - * @remarks - * HTML attribute: type-ramp-plus-6-font-size - * - * CSS custom property: --type-ramp-plus-6-font-size - */ - @attr({ - attribute: 'type-ramp-plus-6-font-size', - }) - @designToken(typeRampPlus6FontSize) - public typeRampPlus6FontSize: string; - - /** - * The line-height six steps above the base line-height - * - * @remarks - * HTML attribute: type-ramp-plus-6-line-height - * - * CSS custom property: --type-ramp-plus-6-line-height - */ - @attr({ - attribute: 'type-ramp-plus-6-line-height', - }) - @designToken(typeRampPlus6LineHeight) - public typeRampPlus6LineHeight: string; - - /** - * The distance from the resolved accent fill color for the rest state of the accent-fill recipe. - * - * @remarks - * HTML attribute: accent-fill-rest-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'accent-fill-rest-delta', - converter: nullableNumberConverter, - }) - @designToken(accentFillRestDelta) - public accentFillRestDelta: number; - - /** - * The distance from the resolved accent fill color for the hover state of the accent-fill recipe. - * - * @remarks - * HTML attribute: accent-fill-hover-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'accent-fill-hover-delta', - converter: nullableNumberConverter, - }) - @designToken(accentFillHoverDelta) - public accentFillHoverDelta: number; - - /** - * The distance from the resolved accent fill color for the active state of the accent-fill recipe. - * - * @remarks - * HTML attribute: accent-fill-active-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'accent-fill-active-delta', - converter: nullableNumberConverter, - }) - @designToken(accentFillActiveDelta) - public accentFillActiveDelta: number; - - /** - * The distance from the resolved accent fill color for the focus state of the accent-fill recipe. - * - * @remarks - * HTML attribute: accent-fill-focus-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'accent-fill-focus-delta', - converter: nullableNumberConverter, - }) - @designToken(accentFillFocusDelta) - public accentFillFocusDelta: number; - - /** - * The distance from the resolved accent foreground color for the rest state of the accent-foreground recipe. - * - * @remarks - * HTML attribute: accent-foreground-rest-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'accent-foreground-rest-delta', - converter: nullableNumberConverter, - }) - @designToken(accentForegroundRestDelta) - public accentForegroundRestDelta: number; - - /** - * The distance from the resolved accent foreground color for the hover state of the accent-foreground recipe. - * - * @remarks - * HTML attribute: accent-foreground-hover-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'accent-foreground-hover-delta', - converter: nullableNumberConverter, - }) - @designToken(accentForegroundHoverDelta) - public accentForegroundHoverDelta: number; - - /** - * The distance from the resolved accent foreground color for the active state of the accent-foreground recipe. - * - * @remarks - * HTML attribute: accent-foreground-active-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'accent-foreground-active-delta', - converter: nullableNumberConverter, - }) - @designToken(accentForegroundActiveDelta) - public accentForegroundActiveDelta: number; - - /** - * The distance from the resolved accent foreground color for the focus state of the accent-foreground recipe. - * - * @remarks - * HTML attribute: accent-foreground-focus-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'accent-foreground-focus-delta', - converter: nullableNumberConverter, - }) - @designToken(accentForegroundFocusDelta) - public accentForegroundFocusDelta: number; - - /** - * The distance from the resolved neutral fill color for the rest state of the neutral-fill recipe. - * - * @remarks - * HTML attribute: neutral-fill-rest-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-rest-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillRestDelta) - public neutralFillRestDelta: number; - - /** - * The distance from the resolved neutral fill color for the hover state of the neutral-fill recipe. - * - * @remarks - * HTML attribute: neutral-fill-hover-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-hover-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillHoverDelta) - public neutralFillHoverDelta: number; - - /** - * The distance from the resolved neutral fill color for the active state of the neutral-fill recipe. - * - * @remarks - * HTML attribute: neutral-fill-active-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-active-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillActiveDelta) - public neutralFillActiveDelta: number; - - /** - * The distance from the resolved neutral fill color for the focus state of the neutral-fill recipe. - * - * @remarks - * HTML attribute: neutral-fill-focus-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-focus-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillFocusDelta) - public neutralFillFocusDelta: number; - - /** - * The distance from the resolved neutral fill input color for the rest state of the neutral-fill-input recipe. - * - * @remarks - * HTML attribute: neutral-fill-input-rest-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-input-rest-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillInputRestDelta) - public neutralFillInputRestDelta: number; - - /** - * The distance from the resolved neutral fill input color for the hover state of the neutral-fill-input recipe. - * - * @remarks - * HTML attribute: neutral-fill-input-hover-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-input-hover-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillInputHoverDelta) - public neutralFillInputHoverDelta: number; - - /** - * The distance from the resolved neutral fill input color for the active state of the neutral-fill-input recipe. - * - * @remarks - * HTML attribute: neutral-fill-input-active-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-input-active-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillInputActiveDelta) - public neutralFillInputActiveDelta: number; - - /** - * The distance from the resolved neutral fill input color for the focus state of the neutral-fill-input recipe. - * - * @remarks - * HTML attribute: neutral-fill-input-focus-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-input-focus-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillInputFocusDelta) - public neutralFillInputFocusDelta: number; - - /** - * The distance from the resolved neutral fill input color for the rest state of the neutral-fill-layer recipe. - * - * @remarks - * HTML attribute: neutral-fill-layer-rest-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-layer-rest-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillLayerRestDelta) - public neutralFillLayerRestDelta: number; - - /** - * The distance from the resolved neutral fill stealth color for the rest state of the neutral-fill-stealth recipe. - * - * @remarks - * HTML attribute: neutral-fill-stealth-rest-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-stealth-rest-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillStealthRestDelta) - public neutralFillStealthRestDelta: number; - - /** - * The distance from the resolved neutral fill stealth color for the hover state of the neutral-fill-stealth recipe. - * - * @remarks - * HTML attribute: neutral-fill-stealth-hover-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-stealth-hover-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillStealthHoverDelta) - public neutralFillStealthHoverDelta: number; - - /** - * The distance from the resolved neutral fill stealth color for the active state of the neutral-fill-stealth recipe. - * - * @remarks - * HTML attribute: neutral-fill-stealth-active-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-stealth-active-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillStealthActiveDelta) - public neutralFillStealthActiveDelta: number; - - /** - * The distance from the resolved neutral fill stealth color for the focus state of the neutral-fill-stealth recipe. - * - * @remarks - * HTML attribute: neutral-fill-stealth-focus-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-stealth-focus-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillStealthFocusDelta) - public neutralFillStealthFocusDelta: number; - - /** - * The distance from the resolved neutral fill strong color for the hover state of the neutral-fill-strong recipe. - * - * @remarks - * HTML attribute: neutral-fill-strong-hover-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-strong-hover-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillStrongHoverDelta) - public neutralFillStrongHoverDelta: number; - - /** - * The distance from the resolved neutral fill strong color for the active state of the neutral-fill-strong recipe. - * - * @remarks - * HTML attribute: neutral-fill-strong-active-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-strong-active-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillStrongActiveDelta) - public neutralFillStrongActiveDelta: number; - - /** - * The distance from the resolved neutral fill strong color for the focus state of the neutral-fill-strong recipe. - * - * @remarks - * HTML attribute: neutral-fill-strong-focus-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-fill-strong-focus-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralFillStrongFocusDelta) - public neutralFillStrongFocusDelta: number; - - /** - * The {@link https://www.w3.org/WAI/GL/wiki/Relative_luminance#:~:text=WCAG%20definition%20of%20relative%20luminance,and%201%20for%20lightest%20white|relative luminance} of the base layer of the application. - * - * @remarks - * When set to a number between 0 and 1 - * - * HTML attribute: base-layer-luminance - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'base-layer-luminance', - converter: nullableNumberConverter, - }) - @designToken(baseLayerLuminance) - public baseLayerLuminance: number; // 0...1 - - /** - * The distance from the resolved divider color for the rest state of the neutral-stroke-divider recipe. - * - * @remarks - * HTML attribute: neutral-stroke-divider-rest-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-stroke-divider-rest-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralStrokeDividerRestDelta) - public neutralStrokeDividerRestDelta: number; - - /** - * The distance from the resolved neutral stroke color for the rest state of the neutral-stroke recipe. - * - * @remarks - * HTML attribute: neutral-stroke-rest-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-stroke-rest-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralStrokeRestDelta) - public neutralStrokeRestDelta: number; - - /** - * The distance from the resolved neutral stroke color for the hover state of the neutral-stroke recipe. - * - * @remarks - * HTML attribute: neutral-stroke-hover-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-stroke-hover-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralStrokeHoverDelta) - public neutralStrokeHoverDelta: number; - - /** - * The distance from the resolved neutral stroke color for the active state of the neutral-stroke recipe. - * - * @remarks - * HTML attribute: neutral-stroke-active-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-stroke-active-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralStrokeActiveDelta) - public neutralStrokeActiveDelta: number; - - /** - * The distance from the resolved neutral stroke color for the focus state of the neutral-stroke recipe. - * - * @remarks - * HTML attribute: neutral-stroke-focus-delta - * - * CSS custom property: N/A - */ - @attr({ - attribute: 'neutral-stroke-focus-delta', - converter: nullableNumberConverter, - }) - @designToken(neutralStrokeFocusDelta) - public neutralStrokeFocusDelta: number; -} - -/** - * The Fluent Design System Provider Element. - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentDesignSystemProvider = DesignSystemProvider.compose({ - baseName: 'design-system-provider', - template: html` `, - styles: css` - ${display('block')} - `, -}); diff --git a/packages/web-components/src/design-tokens.ts b/packages/web-components/src/design-tokens.ts deleted file mode 100644 index e53f0da7c10a1..0000000000000 --- a/packages/web-components/src/design-tokens.ts +++ /dev/null @@ -1,1271 +0,0 @@ -import { DesignToken } from '@microsoft/fast-foundation'; -import { Direction } from '@microsoft/fast-web-utilities'; -import { Palette, PaletteRGB } from './color/palette'; -import { Swatch, SwatchRGB } from './color/swatch'; -import { foregroundOnAccentSet as foregroundOnAccentSetAlgorithm } from './color/recipes/foreground-on-accent'; -import { gradientShadowStroke as gradientShadowStrokeAlgorithm } from './color/recipes/gradient-shadow-stroke'; -import { underlineStroke as underlineStrokeAlgorithm } from './color/recipes/underline-stroke'; -import { contrastSwatch } from './color/recipes/contrast-swatch'; -import { - contrastAndDeltaSwatchSet, - contrastAndDeltaSwatchSetByLuminance, -} from './color/recipes/contrast-and-delta-swatch-set'; -import { deltaSwatch } from './color/recipes/delta-swatch'; -import { deltaSwatchSet, deltaSwatchSetByLuminance } from './color/recipes/delta-swatch-set'; -import { - focusStrokeInner as focusStrokeInnerAlgorithm, - focusStrokeOuter as focusStrokeOuterAlgorithm, -} from './color/recipes/focus-stroke'; -import { neutralLayerFloating as neutralLayerFloatingAlgorithm } from './color/recipes/neutral-layer-floating'; -import { neutralLayer1 as neutralLayer1Algorithm } from './color/recipes/neutral-layer-1'; -import { neutralLayer2 as neutralLayer2Algorithm } from './color/recipes/neutral-layer-2'; -import { neutralLayer3 as neutralLayer3Algorithm } from './color/recipes/neutral-layer-3'; -import { neutralLayer4 as neutralLayer4Algorithm } from './color/recipes/neutral-layer-4'; -import { accentBase, middleGrey } from './color/utilities/color-constants'; -import { StandardLuminance } from './color/utilities/base-layer-luminance'; -import { InteractiveSwatchSet } from './color/recipe'; -import { directionByIsDark } from './color/utilities/direction-by-is-dark'; -import { StandardFontWeight } from './utilities/type-ramp'; - -/** @public @deprecated Use ColorRecipe instead */ -export interface Recipe { - evaluate(element: HTMLElement, reference?: Swatch): T; -} - -/** @public */ -export interface ColorRecipe { - evaluate(element: HTMLElement, reference?: Swatch): Swatch; -} - -/** @public */ -export interface InteractiveColorRecipe { - evaluate(element: HTMLElement, reference?: Swatch): InteractiveSwatchSet; -} - -const { create } = DesignToken; - -function createNonCss(name: string): DesignToken { - return DesignToken.create({ name, cssCustomPropertyName: null }); -} - -// General tokens - -/** @public */ -export const direction = create('direction').withDefault(Direction.ltr); -/** @public */ -export const disabledOpacity = create('disabled-opacity').withDefault(0.3); - -// Density tokens - -/** @public */ -export const baseHeightMultiplier = create('base-height-multiplier').withDefault(8); -/** @public */ -export const baseHorizontalSpacingMultiplier = create('base-horizontal-spacing-multiplier').withDefault(3); -/** @public */ -export const density = create('density').withDefault(0); -/** @public */ -export const designUnit = create('design-unit').withDefault(4); - -// Appearance tokens - -/** @public */ -export const controlCornerRadius = create('control-corner-radius').withDefault(4); -/** @public */ -export const layerCornerRadius = create('layer-corner-radius').withDefault(8); - -/** @public */ -export const strokeWidth = create('stroke-width').withDefault(1); -/** @public */ -export const focusStrokeWidth = create('focus-stroke-width').withDefault(2); - -// Typography values - -/** @public */ -export const bodyFont = create('body-font').withDefault('"Segoe UI Variable", "Segoe UI", sans-serif'); -/** @public */ -export const fontWeight = create('font-weight').withDefault(StandardFontWeight.Normal); - -function fontVariations(sizeToken: DesignToken): (element: HTMLElement) => string { - return (element: HTMLElement): string => { - const size = sizeToken.getValueFor(element); - const weight = fontWeight.getValueFor(element); - if (size.endsWith('px')) { - const px = Number.parseFloat(size.replace('px', '')); - if (px <= 12) { - return `"wght" ${weight}, "opsz" 8`; - } else if (px > 24) { - return `"wght" ${weight}, "opsz" 36`; - } - } - return `"wght" ${weight}, "opsz" 10.5`; - }; -} - -/** @public */ -export const typeRampBaseFontSize = create('type-ramp-base-font-size').withDefault('14px'); -/** @public */ -export const typeRampBaseLineHeight = create('type-ramp-base-line-height').withDefault('20px'); -/** @public */ -export const typeRampBaseFontVariations = create('type-ramp-base-font-variations').withDefault( - fontVariations(typeRampBaseFontSize), -); -/** @public */ -export const typeRampMinus1FontSize = create('type-ramp-minus-1-font-size').withDefault('12px'); -/** @public */ -export const typeRampMinus1LineHeight = create('type-ramp-minus-1-line-height').withDefault('16px'); -/** @public */ -export const typeRampMinus1FontVariations = create('type-ramp-minus-1-font-variations').withDefault( - fontVariations(typeRampMinus1FontSize), -); -/** @public */ -export const typeRampMinus2FontSize = create('type-ramp-minus-2-font-size').withDefault('10px'); -/** @public */ -export const typeRampMinus2LineHeight = create('type-ramp-minus-2-line-height').withDefault('14px'); -/** @public */ -export const typeRampMinus2FontVariations = create('type-ramp-minus-2-font-variations').withDefault( - fontVariations(typeRampMinus2FontSize), -); -/** @public */ -export const typeRampPlus1FontSize = create('type-ramp-plus-1-font-size').withDefault('16px'); -/** @public */ -export const typeRampPlus1LineHeight = create('type-ramp-plus-1-line-height').withDefault('22px'); -/** @public */ -export const typeRampPlus1FontVariations = create('type-ramp-plus-1-font-variations').withDefault( - fontVariations(typeRampPlus1FontSize), -); -/** @public */ -export const typeRampPlus2FontSize = create('type-ramp-plus-2-font-size').withDefault('20px'); -/** @public */ -export const typeRampPlus2LineHeight = create('type-ramp-plus-2-line-height').withDefault('26px'); -/** @public */ -export const typeRampPlus2FontVariations = create('type-ramp-plus-2-font-variations').withDefault( - fontVariations(typeRampPlus2FontSize), -); -/** @public */ -export const typeRampPlus3FontSize = create('type-ramp-plus-3-font-size').withDefault('24px'); -/** @public */ -export const typeRampPlus3LineHeight = create('type-ramp-plus-3-line-height').withDefault('32px'); -/** @public */ -export const typeRampPlus3FontVariations = create('type-ramp-plus-3-font-variations').withDefault( - fontVariations(typeRampPlus3FontSize), -); -/** @public */ -export const typeRampPlus4FontSize = create('type-ramp-plus-4-font-size').withDefault('28px'); -/** @public */ -export const typeRampPlus4LineHeight = create('type-ramp-plus-4-line-height').withDefault('36px'); -/** @public */ -export const typeRampPlus4FontVariations = create('type-ramp-plus-4-font-variations').withDefault( - fontVariations(typeRampPlus4FontSize), -); -/** @public */ -export const typeRampPlus5FontSize = create('type-ramp-plus-5-font-size').withDefault('32px'); -/** @public */ -export const typeRampPlus5LineHeight = create('type-ramp-plus-5-line-height').withDefault('40px'); -/** @public */ -export const typeRampPlus5FontVariations = create('type-ramp-plus-5-font-variations').withDefault( - fontVariations(typeRampPlus5FontSize), -); -/** @public */ -export const typeRampPlus6FontSize = create('type-ramp-plus-6-font-size').withDefault('40px'); -/** @public */ -export const typeRampPlus6LineHeight = create('type-ramp-plus-6-line-height').withDefault('52px'); -/** @public */ -export const typeRampPlus6FontVariations = create('type-ramp-plus-6-font-variations').withDefault( - fontVariations(typeRampPlus6FontSize), -); - -// Color recipe values - -/** @public */ -export const baseLayerLuminance = create('base-layer-luminance').withDefault(StandardLuminance.LightMode); - -/** @public */ -export const accentFillRestDelta = createNonCss('accent-fill-rest-delta').withDefault(0); -/** @public */ -export const accentFillHoverDelta = createNonCss('accent-fill-hover-delta').withDefault(-2); -/** @public */ -export const accentFillActiveDelta = createNonCss('accent-fill-active-delta').withDefault(-5); -/** @public */ -export const accentFillFocusDelta = createNonCss('accent-fill-focus-delta').withDefault(0); - -/** @public */ -export const accentForegroundRestDelta = createNonCss('accent-foreground-rest-delta').withDefault(0); -/** @public */ -export const accentForegroundHoverDelta = createNonCss('accent-foreground-hover-delta').withDefault(3); -/** @public */ -export const accentForegroundActiveDelta = createNonCss('accent-foreground-active-delta').withDefault(-8); -/** @public */ -export const accentForegroundFocusDelta = createNonCss('accent-foreground-focus-delta').withDefault(0); - -/** @public */ -export const neutralFillRestDelta = createNonCss('neutral-fill-rest-delta').withDefault(-1); -/** @public */ -export const neutralFillHoverDelta = createNonCss('neutral-fill-hover-delta').withDefault(1); -/** @public */ -export const neutralFillActiveDelta = createNonCss('neutral-fill-active-delta').withDefault(0); -/** @public */ -export const neutralFillFocusDelta = createNonCss('neutral-fill-focus-delta').withDefault(0); - -/** @public */ -export const neutralFillInputRestDelta = createNonCss('neutral-fill-input-rest-delta').withDefault(-1); -/** @public */ -export const neutralFillInputHoverDelta = createNonCss('neutral-fill-input-hover-delta').withDefault(1); -/** @public */ -export const neutralFillInputActiveDelta = createNonCss('neutral-fill-input-active-delta').withDefault(0); -/** @public */ -export const neutralFillInputFocusDelta = createNonCss('neutral-fill-input-focus-delta').withDefault(-2); - -/** @public */ -export const neutralFillInputAltRestDelta = createNonCss('neutral-fill-input-alt-rest-delta').withDefault(2); -/** @public */ -export const neutralFillInputAltHoverDelta = createNonCss('neutral-fill-input-alt-hover-delta').withDefault(4); -/** @public */ -export const neutralFillInputAltActiveDelta = createNonCss('neutral-fill-input-alt-active-delta').withDefault( - 6, -); -/** @public */ -export const neutralFillInputAltFocusDelta = createNonCss('neutral-fill-input-alt-focus-delta').withDefault(2); - -/** @public */ -export const neutralFillLayerRestDelta = createNonCss('neutral-fill-layer-rest-delta').withDefault(-2); -/** @public */ -export const neutralFillLayerHoverDelta = createNonCss('neutral-fill-layer-hover-delta').withDefault(-3); -/** @public */ -export const neutralFillLayerActiveDelta = createNonCss('neutral-fill-layer-active-delta').withDefault(-3); - -/** @public */ -export const neutralFillLayerAltRestDelta = createNonCss('neutral-fill-layer-alt-rest-delta').withDefault(-1); - -/** @public */ -export const neutralFillSecondaryRestDelta = createNonCss('neutral-fill-secondary-rest-delta').withDefault(3); -/** @public */ -export const neutralFillSecondaryHoverDelta = createNonCss('neutral-fill-secondary-hover-delta').withDefault(2); -/** @public */ -export const neutralFillSecondaryActiveDelta = createNonCss('neutral-fill-secondary-active-delta').withDefault( - 1, -); -/** @public */ -export const neutralFillSecondaryFocusDelta = createNonCss('neutral-fill-secondary-focus-delta').withDefault(3); - -/** @public */ -export const neutralFillStealthRestDelta = createNonCss('neutral-fill-stealth-rest-delta').withDefault(0); -/** @public */ -export const neutralFillStealthHoverDelta = createNonCss('neutral-fill-stealth-hover-delta').withDefault(3); -/** @public */ -export const neutralFillStealthActiveDelta = createNonCss('neutral-fill-stealth-active-delta').withDefault(2); -/** @public */ -export const neutralFillStealthFocusDelta = createNonCss('neutral-fill-stealth-focus-delta').withDefault(0); - -/** @public */ -export const neutralFillStrongRestDelta = createNonCss('neutral-fill-strong-rest-delta').withDefault(0); -/** @public */ -export const neutralFillStrongHoverDelta = createNonCss('neutral-fill-strong-hover-delta').withDefault(8); -/** @public */ -export const neutralFillStrongActiveDelta = createNonCss('neutral-fill-strong-active-delta').withDefault(-5); -/** @public */ -export const neutralFillStrongFocusDelta = createNonCss('neutral-fill-strong-focus-delta').withDefault(0); - -/** @public */ -export const neutralStrokeRestDelta = createNonCss('neutral-stroke-rest-delta').withDefault(8); -/** @public */ -export const neutralStrokeHoverDelta = createNonCss('neutral-stroke-hover-delta').withDefault(12); -/** @public */ -export const neutralStrokeActiveDelta = createNonCss('neutral-stroke-active-delta').withDefault(6); -/** @public */ -export const neutralStrokeFocusDelta = createNonCss('neutral-stroke-focus-delta').withDefault(8); - -/** @public */ -export const neutralStrokeControlRestDelta = createNonCss('neutral-stroke-control-rest-delta').withDefault(3); -/** @public */ -export const neutralStrokeControlHoverDelta = createNonCss('neutral-stroke-control-hover-delta').withDefault(5); -/** @public */ -export const neutralStrokeControlActiveDelta = createNonCss('neutral-stroke-control-active-delta').withDefault( - 5, -); -/** @public */ -export const neutralStrokeControlFocusDelta = createNonCss('neutral-stroke-control-focus-delta').withDefault(5); - -/** @public */ -export const neutralStrokeDividerRestDelta = createNonCss('neutral-stroke-divider-rest-delta').withDefault(4); - -/** @public */ -export const neutralStrokeLayerRestDelta = createNonCss('neutral-stroke-layer-rest-delta').withDefault(3); -/** @public */ -export const neutralStrokeLayerHoverDelta = createNonCss('neutral-stroke-layer-hover-delta').withDefault(3); -/** @public */ -export const neutralStrokeLayerActiveDelta = createNonCss('neutral-stroke-layer-active-delta').withDefault(3); - -/** @public */ -export const neutralStrokeStrongHoverDelta = createNonCss('neutral-stroke-strong-hover-delta').withDefault(0); -/** @public */ -export const neutralStrokeStrongActiveDelta = createNonCss('neutral-stroke-strong-active-delta').withDefault(0); -/** @public */ -export const neutralStrokeStrongFocusDelta = createNonCss('neutral-stroke-strong-focus-delta').withDefault(0); - -// Color recipes - -/** @public */ -export const neutralBaseColor = create('neutral-base-color').withDefault(middleGrey); -/** @public */ -export const neutralPalette = createNonCss('neutral-palette').withDefault((element: HTMLElement) => - PaletteRGB.from(neutralBaseColor.getValueFor(element) as SwatchRGB), -); - -/** @public */ -export const accentBaseColor = create('accent-base-color').withDefault(accentBase); -/** @public */ -export const accentPalette = createNonCss('accent-palette').withDefault((element: HTMLElement) => - PaletteRGB.from(accentBaseColor.getValueFor(element) as SwatchRGB), -); - -// Neutral Layer Card Container -/** @public */ -export const neutralLayerCardContainerRecipe = createNonCss( - 'neutral-layer-card-container-recipe', -).withDefault({ - evaluate: (element: HTMLElement): Swatch => - neutralLayer2Algorithm( - neutralPalette.getValueFor(element), - baseLayerLuminance.getValueFor(element), - neutralFillLayerRestDelta.getValueFor(element), - ), -}); - -/** @public */ -export const neutralLayerCardContainer = create('neutral-layer-card-container').withDefault( - (element: HTMLElement) => neutralLayerCardContainerRecipe.getValueFor(element).evaluate(element), -); - -// Neutral Layer Floating -/** @public */ -export const neutralLayerFloatingRecipe = createNonCss('neutral-layer-floating-recipe').withDefault({ - evaluate: (element: HTMLElement): Swatch => - neutralLayerFloatingAlgorithm( - neutralPalette.getValueFor(element), - baseLayerLuminance.getValueFor(element), - neutralFillLayerRestDelta.getValueFor(element), - ), -}); - -/** @public */ -export const neutralLayerFloating = create('neutral-layer-floating').withDefault((element: HTMLElement) => - neutralLayerFloatingRecipe.getValueFor(element).evaluate(element), -); - -// Neutral Layer 1 -/** @public */ -export const neutralLayer1Recipe = createNonCss('neutral-layer-1-recipe').withDefault({ - evaluate: (element: HTMLElement): Swatch => - neutralLayer1Algorithm(neutralPalette.getValueFor(element), baseLayerLuminance.getValueFor(element)), -}); - -/** @public */ -export const neutralLayer1 = create('neutral-layer-1').withDefault((element: HTMLElement) => - neutralLayer1Recipe.getValueFor(element).evaluate(element), -); - -// Neutral Layer 2 -/** @public */ -export const neutralLayer2Recipe = createNonCss('neutral-layer-2-recipe').withDefault({ - evaluate: (element: HTMLElement): Swatch => - neutralLayer2Algorithm( - neutralPalette.getValueFor(element), - baseLayerLuminance.getValueFor(element), - neutralFillLayerRestDelta.getValueFor(element), - ), -}); - -/** @public */ -export const neutralLayer2 = create('neutral-layer-2').withDefault((element: HTMLElement) => - neutralLayer2Recipe.getValueFor(element).evaluate(element), -); - -// Neutral Layer 3 -/** @public */ -export const neutralLayer3Recipe = createNonCss('neutral-layer-3-recipe').withDefault({ - evaluate: (element: HTMLElement): Swatch => - neutralLayer3Algorithm( - neutralPalette.getValueFor(element), - baseLayerLuminance.getValueFor(element), - neutralFillLayerRestDelta.getValueFor(element), - ), -}); - -/** @public */ -export const neutralLayer3 = create('neutral-layer-3').withDefault((element: HTMLElement) => - neutralLayer3Recipe.getValueFor(element).evaluate(element), -); - -// Neutral Layer 4 -/** @public */ -export const neutralLayer4Recipe = createNonCss('neutral-layer-4-recipe').withDefault({ - evaluate: (element: HTMLElement): Swatch => - neutralLayer4Algorithm( - neutralPalette.getValueFor(element), - baseLayerLuminance.getValueFor(element), - neutralFillLayerRestDelta.getValueFor(element), - ), -}); - -/** @public */ -export const neutralLayer4 = create('neutral-layer-4').withDefault((element: HTMLElement) => - neutralLayer4Recipe.getValueFor(element).evaluate(element), -); - -/** @public */ -export const fillColor = create('fill-color').withDefault(element => neutralLayer1.getValueFor(element)); - -enum ContrastTarget { - normal = 4.5, - large = 3, -} - -// Accent Fill -/** @public */ -export const accentFillRecipe = createNonCss('accent-fill-recipe').withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => - contrastAndDeltaSwatchSetByLuminance( - accentPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - 5, - accentFillRestDelta.getValueFor(element), - accentFillHoverDelta.getValueFor(element), - accentFillActiveDelta.getValueFor(element), - accentFillFocusDelta.getValueFor(element), - undefined, - 8, - accentFillRestDelta.getValueFor(element), - accentFillHoverDelta.getValueFor(element), - accentFillActiveDelta.getValueFor(element), - accentFillFocusDelta.getValueFor(element), - undefined, - ), -}); - -/** @public */ -export const accentFillRest = create('accent-fill-rest').withDefault((element: HTMLElement) => { - return accentFillRecipe.getValueFor(element).evaluate(element).rest; -}); -/** @public */ -export const accentFillHover = create('accent-fill-hover').withDefault((element: HTMLElement) => { - return accentFillRecipe.getValueFor(element).evaluate(element).hover; -}); -/** @public */ -export const accentFillActive = create('accent-fill-active').withDefault((element: HTMLElement) => { - return accentFillRecipe.getValueFor(element).evaluate(element).active; -}); -/** @public */ -export const accentFillFocus = create('accent-fill-focus').withDefault((element: HTMLElement) => { - return accentFillRecipe.getValueFor(element).evaluate(element).focus; -}); - -// Foreground On Accent -/** @public */ -export const foregroundOnAccentRecipe = createNonCss('foreground-on-accent-recipe').withDefault( - { - evaluate: (element: HTMLElement): InteractiveSwatchSet => - foregroundOnAccentSetAlgorithm( - accentFillRest.getValueFor(element), - accentFillHover.getValueFor(element), - accentFillActive.getValueFor(element), - accentFillFocus.getValueFor(element), - ContrastTarget.normal, - ), - }, -); -/** @public */ -export const foregroundOnAccentRest = create('foreground-on-accent-rest').withDefault( - (element: HTMLElement) => foregroundOnAccentRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const foregroundOnAccentHover = create('foreground-on-accent-hover').withDefault( - (element: HTMLElement) => foregroundOnAccentRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const foregroundOnAccentActive = create('foreground-on-accent-active').withDefault( - (element: HTMLElement) => foregroundOnAccentRecipe.getValueFor(element).evaluate(element).active, -); -/** @public */ -export const foregroundOnAccentFocus = create('foreground-on-accent-focus').withDefault( - (element: HTMLElement) => foregroundOnAccentRecipe.getValueFor(element).evaluate(element).focus, -); - -// Accent Foreground -/** @public */ -export const accentForegroundRecipe = createNonCss('accent-foreground-recipe').withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => - contrastAndDeltaSwatchSet( - accentPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - 9.5, - accentForegroundRestDelta.getValueFor(element), - accentForegroundHoverDelta.getValueFor(element), - accentForegroundActiveDelta.getValueFor(element), - accentForegroundFocusDelta.getValueFor(element), - ), -}); - -/** @public */ -export const accentForegroundRest = create('accent-foreground-rest').withDefault( - (element: HTMLElement) => accentForegroundRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const accentForegroundHover = create('accent-foreground-hover').withDefault( - (element: HTMLElement) => accentForegroundRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const accentForegroundActive = create('accent-foreground-active').withDefault( - (element: HTMLElement) => accentForegroundRecipe.getValueFor(element).evaluate(element).active, -); -/** @public */ -export const accentForegroundFocus = create('accent-foreground-focus').withDefault( - (element: HTMLElement) => accentForegroundRecipe.getValueFor(element).evaluate(element).focus, -); - -// Accent Stroke Control -/** @public */ -export const accentStrokeControlRecipe = createNonCss( - 'accent-stroke-control-recipe', -).withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => { - return gradientShadowStrokeAlgorithm( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - -3, - -3, - -3, - -3, - 10, - 1, - undefined, - true, - ); - }, -}); - -/** @public */ -export const accentStrokeControlRest = create('accent-stroke-control-rest').withDefault( - (element: HTMLElement) => - accentStrokeControlRecipe.getValueFor(element).evaluate(element, accentFillRest.getValueFor(element)).rest, -); -/** @public */ -export const accentStrokeControlHover = create('accent-stroke-control-hover').withDefault( - (element: HTMLElement) => - accentStrokeControlRecipe.getValueFor(element).evaluate(element, accentFillHover.getValueFor(element)).hover, -); -/** @public */ -export const accentStrokeControlActive = create('accent-stroke-control-active').withDefault( - (element: HTMLElement) => - accentStrokeControlRecipe.getValueFor(element).evaluate(element, accentFillActive.getValueFor(element)).active, -); -/** @public */ -export const accentStrokeControlFocus = create('accent-stroke-control-focus').withDefault( - (element: HTMLElement) => - accentStrokeControlRecipe.getValueFor(element).evaluate(element, accentFillFocus.getValueFor(element)).focus, -); - -// Neutral Fill -/** @public */ -export const neutralFillRecipe = createNonCss('neutral-fill-recipe').withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => - deltaSwatchSetByLuminance( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - neutralFillRestDelta.getValueFor(element), - neutralFillHoverDelta.getValueFor(element), - neutralFillActiveDelta.getValueFor(element), - neutralFillFocusDelta.getValueFor(element), - undefined, - 2, - 3, - 1, - 2, - undefined, - ), -}); -/** @public */ -export const neutralFillRest = create('neutral-fill-rest').withDefault( - (element: HTMLElement) => neutralFillRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const neutralFillHover = create('neutral-fill-hover').withDefault( - (element: HTMLElement) => neutralFillRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const neutralFillActive = create('neutral-fill-active').withDefault( - (element: HTMLElement) => neutralFillRecipe.getValueFor(element).evaluate(element).active, -); -/** @public */ -export const neutralFillFocus = create('neutral-fill-focus').withDefault( - (element: HTMLElement) => neutralFillRecipe.getValueFor(element).evaluate(element).focus, -); - -// Neutral Fill Input -/** @public */ -export const neutralFillInputRecipe = createNonCss('neutral-fill-input-recipe').withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => - deltaSwatchSetByLuminance( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - neutralFillInputRestDelta.getValueFor(element), - neutralFillInputHoverDelta.getValueFor(element), - neutralFillInputActiveDelta.getValueFor(element), - neutralFillInputFocusDelta.getValueFor(element), - undefined, - 2, - 3, - 1, - 0, - undefined, - ), -}); - -/** @public */ -export const neutralFillInputRest = create('neutral-fill-input-rest').withDefault( - (element: HTMLElement) => neutralFillInputRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const neutralFillInputHover = create('neutral-fill-input-hover').withDefault( - (element: HTMLElement) => neutralFillInputRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const neutralFillInputActive = create('neutral-fill-input-active').withDefault( - (element: HTMLElement) => neutralFillInputRecipe.getValueFor(element).evaluate(element).active, -); -/** @public */ -export const neutralFillInputFocus = create('neutral-fill-input-focus').withDefault( - (element: HTMLElement) => neutralFillInputRecipe.getValueFor(element).evaluate(element).focus, -); - -// Neutral Fill Input Alt -/** @public */ -export const neutralFillInputAltRecipe = createNonCss( - 'neutral-fill-input-alt-recipe', -).withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => - deltaSwatchSetByLuminance( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - neutralFillInputAltRestDelta.getValueFor(element), - neutralFillInputAltHoverDelta.getValueFor(element), - neutralFillInputAltActiveDelta.getValueFor(element), - neutralFillInputAltFocusDelta.getValueFor(element), - 1, - neutralFillInputAltRestDelta.getValueFor(element), - neutralFillInputAltRestDelta.getValueFor(element) - neutralFillInputAltHoverDelta.getValueFor(element), - neutralFillInputAltRestDelta.getValueFor(element) - neutralFillInputAltActiveDelta.getValueFor(element), - neutralFillInputAltFocusDelta.getValueFor(element), - 1, - ), -}); -/** @public */ -export const neutralFillInputAltRest = create('neutral-fill-input-alt-rest').withDefault( - (element: HTMLElement) => neutralFillInputAltRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const neutralFillInputAltHover = create('neutral-fill-input-alt-hover').withDefault( - (element: HTMLElement) => neutralFillInputAltRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const neutralFillInputAltActive = create('neutral-fill-input-alt-active').withDefault( - (element: HTMLElement) => neutralFillInputAltRecipe.getValueFor(element).evaluate(element).active, -); -/** @public */ -export const neutralFillInputAltFocus = create('neutral-fill-input-alt-focus').withDefault( - (element: HTMLElement) => neutralFillInputAltRecipe.getValueFor(element).evaluate(element).focus, -); - -// Neutral Fill Layer -/** @public */ -export const neutralFillLayerRecipe = createNonCss('neutral-fill-layer-recipe').withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => - deltaSwatchSet( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - neutralFillLayerRestDelta.getValueFor(element), - neutralFillLayerHoverDelta.getValueFor(element), - neutralFillLayerActiveDelta.getValueFor(element), - neutralFillLayerRestDelta.getValueFor(element), - 1, - ), -}); - -/** @public */ -export const neutralFillLayerRest = create('neutral-fill-layer-rest').withDefault( - (element: HTMLElement) => neutralFillLayerRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const neutralFillLayerHover = create('neutral-fill-layer-hover').withDefault( - (element: HTMLElement) => neutralFillLayerRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const neutralFillLayerActive = create('neutral-fill-layer-active').withDefault( - (element: HTMLElement) => neutralFillLayerRecipe.getValueFor(element).evaluate(element).active, -); - -// Neutral Fill Layer Alt -/** @public */ -export const neutralFillLayerAltRecipe = createNonCss( - 'neutral-fill-layer-alt-recipe', -).withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => - deltaSwatchSet( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - neutralFillLayerAltRestDelta.getValueFor(element), - neutralFillLayerAltRestDelta.getValueFor(element), - neutralFillLayerAltRestDelta.getValueFor(element), - neutralFillLayerAltRestDelta.getValueFor(element), - ), -}); -/** @public */ -export const neutralFillLayerAltRest = create('neutral-fill-layer-alt-rest').withDefault( - (element: HTMLElement) => neutralFillLayerAltRecipe.getValueFor(element).evaluate(element).rest, -); - -// Neutral Fill Secondary -/** @public */ -export const neutralFillSecondaryRecipe = createNonCss( - 'neutral-fill-secondary-recipe', -).withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => - deltaSwatchSet( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - neutralFillSecondaryRestDelta.getValueFor(element), - neutralFillSecondaryHoverDelta.getValueFor(element), - neutralFillSecondaryActiveDelta.getValueFor(element), - neutralFillSecondaryFocusDelta.getValueFor(element), - ), -}); -/** @public */ -export const neutralFillSecondaryRest = create('neutral-fill-secondary-rest').withDefault( - (element: HTMLElement) => neutralFillSecondaryRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const neutralFillSecondaryHover = create('neutral-fill-secondary-hover').withDefault( - (element: HTMLElement) => neutralFillSecondaryRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const neutralFillSecondaryActive = create('neutral-fill-secondary-active').withDefault( - (element: HTMLElement) => neutralFillSecondaryRecipe.getValueFor(element).evaluate(element).active, -); -/** @public */ -export const neutralFillSecondaryFocus = create('neutral-fill-secondary-focus').withDefault( - (element: HTMLElement) => neutralFillSecondaryRecipe.getValueFor(element).evaluate(element).focus, -); - -// Neutral Fill Stealth -/** @public */ -export const neutralFillStealthRecipe = createNonCss('neutral-fill-stealth-recipe').withDefault( - { - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => - deltaSwatchSet( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - neutralFillStealthRestDelta.getValueFor(element), - neutralFillStealthHoverDelta.getValueFor(element), - neutralFillStealthActiveDelta.getValueFor(element), - neutralFillStealthFocusDelta.getValueFor(element), - ), - }, -); - -/** @public */ -export const neutralFillStealthRest = create('neutral-fill-stealth-rest').withDefault( - (element: HTMLElement) => neutralFillStealthRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const neutralFillStealthHover = create('neutral-fill-stealth-hover').withDefault( - (element: HTMLElement) => neutralFillStealthRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const neutralFillStealthActive = create('neutral-fill-stealth-active').withDefault( - (element: HTMLElement) => neutralFillStealthRecipe.getValueFor(element).evaluate(element).active, -); -/** @public */ -export const neutralFillStealthFocus = create('neutral-fill-stealth-focus').withDefault( - (element: HTMLElement) => neutralFillStealthRecipe.getValueFor(element).evaluate(element).focus, -); - -// Neutral Fill Strong -/** @public */ -export const neutralFillStrongRecipe = createNonCss('neutral-fill-strong-recipe').withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => - contrastAndDeltaSwatchSet( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - 4.5, - neutralFillStrongRestDelta.getValueFor(element), - neutralFillStrongHoverDelta.getValueFor(element), - neutralFillStrongActiveDelta.getValueFor(element), - neutralFillStrongFocusDelta.getValueFor(element), - ), -}); - -/** @public */ -export const neutralFillStrongRest = create('neutral-fill-strong-rest').withDefault( - (element: HTMLElement) => neutralFillStrongRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const neutralFillStrongHover = create('neutral-fill-strong-hover').withDefault( - (element: HTMLElement) => neutralFillStrongRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const neutralFillStrongActive = create('neutral-fill-strong-active').withDefault( - (element: HTMLElement) => neutralFillStrongRecipe.getValueFor(element).evaluate(element).active, -); -/** @public */ -export const neutralFillStrongFocus = create('neutral-fill-strong-focus').withDefault( - (element: HTMLElement) => neutralFillStrongRecipe.getValueFor(element).evaluate(element).focus, -); - -// Neutral Foreground -/** @public */ -export const neutralForegroundRecipe = createNonCss('neutral-foreground-recipe').withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => - contrastAndDeltaSwatchSet( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - 16, - 0, - -19, - -30, - 0, - ), -}); - -/** @public */ -export const neutralForegroundRest = create('neutral-foreground-rest').withDefault( - (element: HTMLElement) => neutralForegroundRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const neutralForegroundHover = create('neutral-foreground-hover').withDefault( - (element: HTMLElement) => neutralForegroundRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const neutralForegroundActive = create('neutral-foreground-active').withDefault( - (element: HTMLElement) => neutralForegroundRecipe.getValueFor(element).evaluate(element).active, -); -/** @public */ -export const neutralForegroundFocus = create('neutral-foreground-focus').withDefault( - (element: HTMLElement) => neutralForegroundRecipe.getValueFor(element).evaluate(element).focus, -); - -// Neutral Foreground Hint -/** @public */ -export const neutralForegroundHintRecipe = createNonCss('neutral-foreground-hint-recipe').withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): Swatch => - contrastSwatch(neutralPalette.getValueFor(element), reference || fillColor.getValueFor(element), 4.5), -}); - -/** @public */ -export const neutralForegroundHint = create('neutral-foreground-hint').withDefault((element: HTMLElement) => - neutralForegroundHintRecipe.getValueFor(element).evaluate(element), -); - -// Neutral Stroke -/** @public */ -export const neutralStrokeRecipe = createNonCss('neutral-stroke-recipe').withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => { - return deltaSwatchSet( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - neutralStrokeRestDelta.getValueFor(element), - neutralStrokeHoverDelta.getValueFor(element), - neutralStrokeActiveDelta.getValueFor(element), - neutralStrokeFocusDelta.getValueFor(element), - ); - }, -}); - -/** @public */ -export const neutralStrokeRest = create('neutral-stroke-rest').withDefault( - (element: HTMLElement) => neutralStrokeRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const neutralStrokeHover = create('neutral-stroke-hover').withDefault( - (element: HTMLElement) => neutralStrokeRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const neutralStrokeActive = create('neutral-stroke-active').withDefault( - (element: HTMLElement) => neutralStrokeRecipe.getValueFor(element).evaluate(element).active, -); -/** @public */ -export const neutralStrokeFocus = create('neutral-stroke-focus').withDefault( - (element: HTMLElement) => neutralStrokeRecipe.getValueFor(element).evaluate(element).focus, -); - -// Neutral Stroke Control -/** @public */ -export const neutralStrokeControlRecipe = createNonCss( - 'neutral-stroke-control-recipe', -).withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => { - return gradientShadowStrokeAlgorithm( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - neutralStrokeControlRestDelta.getValueFor(element), - neutralStrokeControlHoverDelta.getValueFor(element), - neutralStrokeControlActiveDelta.getValueFor(element), - neutralStrokeControlFocusDelta.getValueFor(element), - 5, - ); - }, -}); - -/** @public */ -export const neutralStrokeControlRest = create('neutral-stroke-control-rest').withDefault( - (element: HTMLElement) => neutralStrokeControlRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const neutralStrokeControlHover = create('neutral-stroke-control-hover').withDefault( - (element: HTMLElement) => neutralStrokeControlRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const neutralStrokeControlActive = create('neutral-stroke-control-active').withDefault( - (element: HTMLElement) => neutralStrokeControlRecipe.getValueFor(element).evaluate(element).active, -); -/** @public */ -export const neutralStrokeControlFocus = create('neutral-stroke-control-focus').withDefault( - (element: HTMLElement) => neutralStrokeControlRecipe.getValueFor(element).evaluate(element).focus, -); - -// Neutral Stroke Divider -/** @public */ -export const neutralStrokeDividerRecipe = createNonCss('neutral-stroke-divider-recipe').withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): Swatch => - deltaSwatch( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - neutralStrokeDividerRestDelta.getValueFor(element), - ), -}); - -/** @public */ -export const neutralStrokeDividerRest = create('neutral-stroke-divider-rest').withDefault(element => - neutralStrokeDividerRecipe.getValueFor(element).evaluate(element), -); - -// Neutral Stroke Input -/** @public */ -export const neutralStrokeInputRecipe = createNonCss('neutral-stroke-input-recipe').withDefault( - { - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => { - return underlineStrokeAlgorithm( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - neutralStrokeControlRestDelta.getValueFor(element), - neutralStrokeControlHoverDelta.getValueFor(element), - neutralStrokeControlActiveDelta.getValueFor(element), - neutralStrokeControlFocusDelta.getValueFor(element), - 20, - strokeWidth.getValueFor(element) + 'px', - ); - }, - }, -); - -/** @public */ -export const neutralStrokeInputRest = create('neutral-stroke-input-rest').withDefault( - (element: HTMLElement) => neutralStrokeInputRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const neutralStrokeInputHover = create('neutral-stroke-input-hover').withDefault( - (element: HTMLElement) => neutralStrokeInputRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const neutralStrokeInputActive = create('neutral-stroke-input-active').withDefault( - (element: HTMLElement) => neutralStrokeInputRecipe.getValueFor(element).evaluate(element).active, -); -/** @public */ -export const neutralStrokeInputFocus = create('neutral-stroke-input-focus').withDefault( - (element: HTMLElement) => neutralStrokeInputRecipe.getValueFor(element).evaluate(element).focus, -); - -// Neutral Stroke Layer -/** @public */ -export const neutralStrokeLayerRecipe = createNonCss('neutral-stroke-layer-recipe').withDefault( - { - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => { - return deltaSwatchSet( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - neutralStrokeLayerRestDelta.getValueFor(element), - neutralStrokeLayerHoverDelta.getValueFor(element), - neutralStrokeLayerActiveDelta.getValueFor(element), - neutralStrokeLayerRestDelta.getValueFor(element), - ); - }, - }, -); - -/** @public */ -export const neutralStrokeLayerRest = create('neutral-stroke-layer-rest').withDefault( - (element: HTMLElement) => neutralStrokeLayerRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const neutralStrokeLayerHover = create('neutral-stroke-layer-hover').withDefault( - (element: HTMLElement) => neutralStrokeLayerRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const neutralStrokeLayerActive = create('neutral-stroke-layer-active').withDefault( - (element: HTMLElement) => neutralStrokeLayerRecipe.getValueFor(element).evaluate(element).active, -); - -// Neutral Stroke Strong -/** @public */ -export const neutralStrokeStrongRecipe = createNonCss( - 'neutral-stroke-strong-recipe', -).withDefault({ - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => - contrastAndDeltaSwatchSet( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - 5.5, - 0, - neutralStrokeStrongHoverDelta.getValueFor(element), - neutralStrokeStrongActiveDelta.getValueFor(element), - neutralStrokeStrongFocusDelta.getValueFor(element), - ), -}); - -/** @public */ -export const neutralStrokeStrongRest = create('neutral-stroke-strong-rest').withDefault( - (element: HTMLElement) => neutralStrokeStrongRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public */ -export const neutralStrokeStrongHover = create('neutral-stroke-strong-hover').withDefault( - (element: HTMLElement) => neutralStrokeStrongRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public */ -export const neutralStrokeStrongActive = create('neutral-stroke-strong-active').withDefault( - (element: HTMLElement) => neutralStrokeStrongRecipe.getValueFor(element).evaluate(element).active, -); -/** @public */ -export const neutralStrokeStrongFocus = create('neutral-stroke-strong-focus').withDefault( - (element: HTMLElement) => neutralStrokeStrongRecipe.getValueFor(element).evaluate(element).focus, -); - -// Focus Stroke Outer -/** @public */ -export const focusStrokeOuterRecipe = createNonCss('focus-stroke-outer-recipe').withDefault({ - evaluate: (element: HTMLElement): Swatch => - focusStrokeOuterAlgorithm(neutralPalette.getValueFor(element), fillColor.getValueFor(element)), -}); - -/** @public */ -export const focusStrokeOuter = create('focus-stroke-outer').withDefault((element: HTMLElement) => - focusStrokeOuterRecipe.getValueFor(element).evaluate(element), -); - -// Focus Stroke Inner -/** @public */ -export const focusStrokeInnerRecipe = createNonCss('focus-stroke-inner-recipe').withDefault({ - evaluate: (element: HTMLElement): Swatch => - focusStrokeInnerAlgorithm( - accentPalette.getValueFor(element), - fillColor.getValueFor(element), - focusStrokeOuter.getValueFor(element), - ), -}); - -/** @public */ -export const focusStrokeInner = create('focus-stroke-inner').withDefault((element: HTMLElement) => - focusStrokeInnerRecipe.getValueFor(element).evaluate(element), -); - -// Deprecated tokens - -// Foreground On Accent -/** @public @deprecated Not used */ -export const foregroundOnAccentLargeRecipe = createNonCss( - 'foreground-on-accent-large-recipe', -).withDefault({ - evaluate: (element: HTMLElement): InteractiveSwatchSet => - foregroundOnAccentSetAlgorithm( - accentFillRest.getValueFor(element), - accentFillHover.getValueFor(element), - accentFillActive.getValueFor(element), - accentFillFocus.getValueFor(element), - ContrastTarget.large, - ), -}); -/** @public @deprecated Not used */ -export const foregroundOnAccentRestLarge = create('foreground-on-accent-rest-large').withDefault( - (element: HTMLElement) => foregroundOnAccentLargeRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public @deprecated Not used */ -export const foregroundOnAccentHoverLarge = create('foreground-on-accent-hover-large').withDefault( - (element: HTMLElement) => - foregroundOnAccentLargeRecipe.getValueFor(element).evaluate(element, accentFillHover.getValueFor(element)).hover, -); -/** @public @deprecated Not used */ -export const foregroundOnAccentActiveLarge = create('foreground-on-accent-active-large').withDefault( - (element: HTMLElement) => - foregroundOnAccentLargeRecipe.getValueFor(element).evaluate(element, accentFillActive.getValueFor(element)).active, -); -/** @public @deprecated Not used */ -export const foregroundOnAccentFocusLarge = create('foreground-on-accent-focus-large').withDefault( - (element: HTMLElement) => - foregroundOnAccentLargeRecipe.getValueFor(element).evaluate(element, accentFillFocus.getValueFor(element)).focus, -); - -// Neutral Fill Inverse -/** @public @deprecated Not used */ -export const neutralFillInverseRestDelta = create('neutral-fill-inverse-rest-delta').withDefault(0); -/** @public @deprecated Not used */ -export const neutralFillInverseHoverDelta = create('neutral-fill-inverse-hover-delta').withDefault(-3); -/** @public @deprecated Not used */ -export const neutralFillInverseActiveDelta = create('neutral-fill-inverse-active-delta').withDefault(7); -/** @public @deprecated Not used */ -export const neutralFillInverseFocusDelta = create('neutral-fill-inverse-focus-delta').withDefault(0); - -/** @deprecated Not used */ -function neutralFillInverse( - palette: Palette, - reference: Swatch, - restDelta: number, - hoverDelta: number, - activeDelta: number, - focusDelta: number, -): InteractiveSwatchSet { - const direction = directionByIsDark(reference); - const accessibleIndex = palette.closestIndexOf(palette.colorContrast(reference, 14)); - const accessibleIndex2 = accessibleIndex + direction * Math.abs(restDelta - hoverDelta); - const indexOneIsRest = direction === 1 ? restDelta < hoverDelta : direction * restDelta > direction * hoverDelta; - let restIndex: number; - let hoverIndex: number; - - if (indexOneIsRest) { - restIndex = accessibleIndex; - hoverIndex = accessibleIndex2; - } else { - restIndex = accessibleIndex2; - hoverIndex = accessibleIndex; - } - - return { - rest: palette.get(restIndex), - hover: palette.get(hoverIndex), - active: palette.get(restIndex + direction * activeDelta), - focus: palette.get(restIndex + direction * focusDelta), - }; -} - -/** @public @deprecated Not used */ -export const neutralFillInverseRecipe = createNonCss('neutral-fill-inverse-recipe').withDefault( - { - evaluate: (element: HTMLElement, reference?: Swatch): InteractiveSwatchSet => - neutralFillInverse( - neutralPalette.getValueFor(element), - reference || fillColor.getValueFor(element), - neutralFillInverseRestDelta.getValueFor(element), - neutralFillInverseHoverDelta.getValueFor(element), - neutralFillInverseActiveDelta.getValueFor(element), - neutralFillInverseFocusDelta.getValueFor(element), - ), - }, -); - -/** @public @deprecated Not used */ -export const neutralFillInverseRest = create('neutral-fill-inverse-rest').withDefault( - (element: HTMLElement) => neutralFillInverseRecipe.getValueFor(element).evaluate(element).rest, -); -/** @public @deprecated Not used */ -export const neutralFillInverseHover = create('neutral-fill-inverse-hover').withDefault( - (element: HTMLElement) => neutralFillInverseRecipe.getValueFor(element).evaluate(element).hover, -); -/** @public @deprecated Not used */ -export const neutralFillInverseActive = create('neutral-fill-inverse-active').withDefault( - (element: HTMLElement) => neutralFillInverseRecipe.getValueFor(element).evaluate(element).active, -); -/** @public @deprecated Not used */ -export const neutralFillInverseFocus = create('neutral-fill-inverse-focus').withDefault( - (element: HTMLElement) => neutralFillInverseRecipe.getValueFor(element).evaluate(element).focus, -); - -/** @public @deprecated Use controlCornerRadius */ -export const cornerRadius = controlCornerRadius; -/** @public @deprecated Use layerCornerRadius */ -export const elevatedCornerRadius = layerCornerRadius; -/** @public @deprecated Use strokeWidth */ -export const outlineWidth = strokeWidth; -/** @public @deprecated Use focusStrokeWidth */ -export const focusOutlineWidth = focusStrokeWidth; - -/** @public @deprecated Use neutralFillInverseRestDelta */ -export const neutralContrastFillRestDelta = neutralFillInverseRestDelta; -/** @public @deprecated Use neutralFillInverseHoverDelta */ -export const neutralContrastFillHoverDelta = neutralFillInverseHoverDelta; -/** @public @deprecated Use neutralFillInverseActiveDelta */ -export const neutralContrastFillActiveDelta = neutralFillInverseActiveDelta; -/** @public @deprecated Use neutralFillInverseFocusDelta */ -export const neutralContrastFillFocusDelta = neutralFillInverseFocusDelta; - -/** @public @deprecated Use neutralFillLayerRestDelta */ -export const neutralFillCardDelta = neutralFillLayerRestDelta; - -/** @public @deprecated Use neutralFillStrongRestDelta */ -export const neutralFillToggleRestDelta = neutralFillStrongRestDelta; -/** @public @deprecated Use neutralFillStrongHoverDelta */ -export const neutralFillToggleHoverDelta = neutralFillStrongHoverDelta; -/** @public @deprecated Use neutralFillStrongActiveDelta */ -export const neutralFillToggleActiveDelta = neutralFillStrongActiveDelta; -/** @public @deprecated Use neutralFillStrongFocusDelta */ -export const neutralFillToggleFocusDelta = neutralFillStrongFocusDelta; - -/** @public @deprecated Use neutralStrokeDividerRestDelta */ -export const neutralDividerRestDelta = neutralStrokeDividerRestDelta; - -/** @public @deprecated Use neutralLayer1 */ -export const neutralLayerL1 = neutralLayer1; -/** @public @deprecated Use neutralLayer2 */ -export const neutralLayerL2 = neutralLayer2; -/** @public @deprecated Use neutralLayer3 */ -export const neutralLayerL3 = neutralLayer3; -/** @public @deprecated Use neutralLayer4 */ -export const neutralLayerL4 = neutralLayer4; - -/** @public @deprecated Use foregroundOnAccentRest */ -export const accentForegroundCut = foregroundOnAccentRest; -/** @public @deprecated Use foregroundOnAccentRestLarge */ -export const accentForegroundCutLarge = foregroundOnAccentRestLarge; - -/** @public @deprecated Use neutralStrokeDividerRest */ -export const neutralDivider = neutralStrokeDividerRest; - -/** @public @deprecated Use neutralFillLayerRest */ -export const neutralFillCard = neutralFillLayerRest; - -/** @public @deprecated Use neutralFillInverseRest */ -export const neutralContrastFillRest = neutralFillInverseRest; -/** @public @deprecated Use neutralFillInverseHover */ -export const neutralContrastFillHover = neutralFillInverseHover; -/** @public @deprecated Use neutralFillInverseActive */ -export const neutralContrastFillActive = neutralFillInverseActive; -/** @public @deprecated Use neutralFillInverseFocus */ -export const neutralContrastFillFocus = neutralFillInverseFocus; - -/** @public @deprecated Use neutralFillStrongRest */ -export const neutralFillToggleRest = neutralFillStrongRest; -/** @public @deprecated Use neutralFillStrongHover */ -export const neutralFillToggleHover = neutralFillStrongHover; -/** @public @deprecated Use neutralFillStrongActive */ -export const neutralFillToggleActive = neutralFillStrongActive; -/** @public @deprecated Use neutralFillStrongFocus */ -export const neutralFillToggleFocus = neutralFillStrongFocus; - -/** @public @deprecated Use focusStrokeOuter */ -export const neutralFocus = focusStrokeOuter; -/** @public @deprecated Use focusStrokeInner */ -export const neutralFocusInnerAccent = focusStrokeInner; - -/** @public @deprecated Use neutralStrokeRest */ -export const neutralOutlineRest = neutralStrokeRest; -/** @public @deprecated Use neutralStrokeHover */ -export const neutralOutlineHover = neutralStrokeHover; -/** @public @deprecated Use neutralStrokeActive */ -export const neutralOutlineActive = neutralStrokeActive; -/** @public @deprecated Use neutralStrokeFocus */ -export const neutralOutlineFocus = neutralStrokeFocus; diff --git a/packages/web-components/src/dialog/dialog.stories.ts b/packages/web-components/src/dialog/dialog.stories.ts deleted file mode 100644 index 403cd33b91aa2..0000000000000 --- a/packages/web-components/src/dialog/dialog.stories.ts +++ /dev/null @@ -1,42 +0,0 @@ -import DialogTemplate from './fixtures/dialog.html'; -import DialogFastButtonsTemplate from './fixtures/dialog-button-test.html'; -import './index'; - -export default { - title: 'Components/Dialog', -}; - -export const Dialog = (): string => DialogTemplate; -export const DialogButtonTest = (): string => DialogFastButtonsTemplate; - -const dialogExample = ` - -

Dialog with text and button. The button should recieve focus

- - -
-`; - -Dialog.parameters = { - docs: { - source: { - code: dialogExample, - }, - }, -}; - -const dialogButtonTestExample = ` - -

Dialog with text and fluent buttons. The first button should receive focus

- Button Text - Button Text -
-`; - -DialogButtonTest.parameters = { - docs: { - source: { - code: dialogButtonTestExample, - }, - }, -}; diff --git a/packages/web-components/src/dialog/dialog.styles.ts b/packages/web-components/src/dialog/dialog.styles.ts deleted file mode 100644 index f5a2047cd6b60..0000000000000 --- a/packages/web-components/src/dialog/dialog.styles.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { ElementDefinitionContext, FoundationElementDefinition } from '@microsoft/fast-foundation'; -import { elevationShadowDialog } from '../styles'; -import { fillColor, layerCornerRadius, strokeWidth } from '../design-tokens'; - -export const dialogStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => css` - :host([hidden]) { - display: none; - } - - :host { - --dialog-height: 480px; - --dialog-width: 640px; - display: block; - } - - .overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.3); - touch-action: none; - } - - .positioning-region { - display: flex; - justify-content: center; - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; - overflow: auto; - } - - .control { - box-shadow: ${elevationShadowDialog}; - margin-top: auto; - margin-bottom: auto; - border-radius: calc(${layerCornerRadius} * 1px); - width: var(--dialog-width); - height: var(--dialog-height); - background: ${fillColor}; - z-index: 1; - border: calc(${strokeWidth} * 1px) solid transparent; - } -`; diff --git a/packages/web-components/src/dialog/dialog.vscode.definition.json b/packages/web-components/src/dialog/dialog.vscode.definition.json deleted file mode 100644 index 48d225835b306..0000000000000 --- a/packages/web-components/src/dialog/dialog.vscode.definition.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-dialog", - "title": "Dialog", - "description": "The Fluent UI dialog element", - "attributes": [ - { - "name": "modal", - "title": "Modal", - "type": "boolean", - "description": "When modal, user interaction will be limited to the contents of the element", - "default": true, - "required": false - }, - { - "name": "hidden", - "title": "Hidden", - "description": "The hidden state of the element", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "trap-focus", - "title": "Trap focus", - "description": "Indicates that the dialog should trap focus", - "type": "boolean", - "default": true, - "required": false - }, - { - "name": "aria-describedby", - "title": "Accessibility description ID", - "description": "The HTML aria-describedby attribute", - "type": "string", - "default": false, - "required": false - }, - { - "name": "aria-labelledby", - "title": "Accessibility label ID", - "description": "The HTML aria-labelledby attribute", - "type": "string", - "default": false, - "required": false - }, - { - "name": "aria-label", - "title": "Accessibility label", - "description": "The HTML aria-label attribute", - "type": "string", - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The dialog content" - } - ] - } - ] -} diff --git a/packages/web-components/src/dialog/fixtures/dialog-button-test.html b/packages/web-components/src/dialog/fixtures/dialog-button-test.html deleted file mode 100644 index 7d3c30e63bb6d..0000000000000 --- a/packages/web-components/src/dialog/fixtures/dialog-button-test.html +++ /dev/null @@ -1,5 +0,0 @@ - -

Dialog with text and fluent buttons. The first button should receive focus

- Button Text - Button Text -
diff --git a/packages/web-components/src/dialog/fixtures/dialog.html b/packages/web-components/src/dialog/fixtures/dialog.html deleted file mode 100644 index cad728e646719..0000000000000 --- a/packages/web-components/src/dialog/fixtures/dialog.html +++ /dev/null @@ -1,5 +0,0 @@ - -

Dialog with text and button. The button should recieve focus

- - -
diff --git a/packages/web-components/src/dialog/index.ts b/packages/web-components/src/dialog/index.ts deleted file mode 100644 index f49c056c9aa6e..0000000000000 --- a/packages/web-components/src/dialog/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Dialog, dialogTemplate as template } from '@microsoft/fast-foundation'; -import { dialogStyles as styles } from './dialog.styles'; - -/** - * The Fluent Dialog Element. Implements {@link @microsoft/fast-foundation#Dialog}, - * {@link @microsoft/fast-foundation#dialogTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentDialog = Dialog.compose({ - baseName: 'dialog', - template, - styles, -}); - -/** - * Styles for Dialog - * @public - */ -export const dialogStyles = styles; - -/** - * Base Dialog Class - * @public - */ -export { Dialog }; diff --git a/packages/web-components/src/divider/divider.stories.ts b/packages/web-components/src/divider/divider.stories.ts deleted file mode 100644 index eec97b650f422..0000000000000 --- a/packages/web-components/src/divider/divider.stories.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { fluentDivider } from './index'; - -export default { - title: 'Components/Divider', - component: fluentDivider, - argTypes: { - orientation: { - description: 'This controls the orientation', - control: { type: 'select' }, - options: ['horizontal', 'vertical'], - default: 'horizontal', - }, - role: { - description: 'This controls the role', - control: { type: 'select' }, - options: ['presentation', 'separator'], - default: 'presentation', - }, - }, -}; - -const DividerTemplate = ({ orientation, role }) => - `
-
`; - -export const Divider = DividerTemplate.bind({}); - -Divider.args = { - orientation: 'horizontal', - role: 'presentation', -}; - -const example = ` - -`; - -Divider.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/divider/divider.styles.ts b/packages/web-components/src/divider/divider.styles.ts deleted file mode 100644 index 12b01f36f446c..0000000000000 --- a/packages/web-components/src/divider/divider.styles.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { display, ElementDefinitionContext, FoundationElementDefinition } from '@microsoft/fast-foundation'; -import { designUnit, neutralStrokeDividerRest, strokeWidth } from '../design-tokens'; - -export const dividerStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - ${display('block')} :host { - box-sizing: content-box; - height: 0; - border: none; - border-top: calc(${strokeWidth} * 1px) solid ${neutralStrokeDividerRest}; - } - - :host([orientation="vertical"]) { - border: none; - height: 100%; - margin: 0 calc(${designUnit} * 1px); - border-left: calc(${strokeWidth} * 1px) solid ${neutralStrokeDividerRest}; - } - `; diff --git a/packages/web-components/src/divider/divider.vscode.definition.json b/packages/web-components/src/divider/divider.vscode.definition.json deleted file mode 100644 index caf617bf48cd3..0000000000000 --- a/packages/web-components/src/divider/divider.vscode.definition.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-divider", - "title": "Divider", - "description": "The Fluent UI divider element", - "attributes": [ - { - "name": "role", - "title": "Role", - "type": "string", - "description": "The ARIA role for the divider", - "values": [ - { - "name": "separator" - }, - { - "name": "presentation" - } - ], - "default": "separator", - "required": false - } - ], - "slots": [] - } - ] -} diff --git a/packages/web-components/src/divider/fixtures/divider.html b/packages/web-components/src/divider/fixtures/divider.html deleted file mode 100644 index db6f05e026f34..0000000000000 --- a/packages/web-components/src/divider/fixtures/divider.html +++ /dev/null @@ -1,6 +0,0 @@ -

Divider

-

Default

- - -

Presentation

- diff --git a/packages/web-components/src/divider/index.ts b/packages/web-components/src/divider/index.ts deleted file mode 100644 index d468f34455180..0000000000000 --- a/packages/web-components/src/divider/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Divider, dividerTemplate as template } from '@microsoft/fast-foundation'; -import { dividerStyles as styles } from './divider.styles'; - -/** - * The Fluent Divider Element. Implements {@link @microsoft/fast-foundation#Divider}, - * {@link @microsoft/fast-foundation#dividerTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentDivider = Divider.compose({ - baseName: 'divider', - template, - styles, -}); - -/** - * Styles for Divider - * @public - */ -export const dividerStyles = styles; - -/** - * Base class for Fluent Divider - * @public - */ -export { Divider }; diff --git a/packages/web-components/src/empty.spec.ts b/packages/web-components/src/empty.spec.ts new file mode 100644 index 0000000000000..46652926eee0f --- /dev/null +++ b/packages/web-components/src/empty.spec.ts @@ -0,0 +1,3 @@ +describe('empty test', (): void => { + it('should pass', (): void => {}); +}); diff --git a/packages/web-components/src/flipper/fixtures/flipper.html b/packages/web-components/src/flipper/fixtures/flipper.html deleted file mode 100644 index 7bc8740d7856d..0000000000000 --- a/packages/web-components/src/flipper/fixtures/flipper.html +++ /dev/null @@ -1,33 +0,0 @@ -

Flipper

-

Default

- - -

Previous

- - -

Previous with slotted content

- - - - - - -

Next

- - -

Next with slotted content

- - - - - - -

With aria-hidden set to false

- - -

Disabled

- diff --git a/packages/web-components/src/flipper/flipper.stories.ts b/packages/web-components/src/flipper/flipper.stories.ts deleted file mode 100644 index fe49db5c1fb22..0000000000000 --- a/packages/web-components/src/flipper/flipper.stories.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { fluentFlipper } from './index'; - -export default { - title: 'Components/Flipper', - component: fluentFlipper, - argTypes: { - direction: { - options: ['previous', 'next'], - control: { type: 'select' }, - }, - disabled: { type: 'boolean' }, - }, -}; - -const FlipperTemplate = ({ direction, disabled, content }) => - ``; - -export const Flipper = FlipperTemplate.bind({}); - -Flipper.args = { - disabled: false, - direction: 'next', -}; - -const example = ` - -`; - -Flipper.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/flipper/flipper.styles.ts b/packages/web-components/src/flipper/flipper.styles.ts deleted file mode 100644 index 397069fda8ef0..0000000000000 --- a/packages/web-components/src/flipper/flipper.styles.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - disabledCursor, - display, - ElementDefinitionContext, - FlipperOptions, - focusVisible, - forcedColorsStylesheetBehavior, -} from '@microsoft/fast-foundation'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { heightNumber } from '../styles'; -import { - controlCornerRadius, - designUnit, - disabledOpacity, - neutralFillRest, - neutralFillStrongActive, - neutralFillStrongHover, - neutralFillStrongRest, - neutralStrokeControlRest, - strokeWidth, -} from '../design-tokens'; -import { focusTreatmentBase } from '../styles/focus'; - -export const flipperStyles: (context: ElementDefinitionContext, definition: FlipperOptions) => ElementStyles = ( - context: ElementDefinitionContext, - definition: FlipperOptions, -) => - css` - ${display('inline-flex')} :host { - height: calc((${heightNumber} + ${designUnit}) * 1px); - justify-content: center; - align-items: center; - fill: currentcolor; - color: ${neutralFillStrongRest}; - background: padding-box linear-gradient(${neutralFillRest}, ${neutralFillRest}), - border-box ${neutralStrokeControlRest}; - box-sizing: border-box; - border: calc(${strokeWidth} * 1px) solid transparent; - border-radius: calc(${controlCornerRadius} * 1px); - padding: 0; - } - - :host(.disabled) { - opacity: ${disabledOpacity}; - cursor: ${disabledCursor}; - pointer-events: none; - } - - .next, - .previous { - display: flex; - } - - :host(:not(.disabled):hover) { - cursor: pointer; - } - - :host(:not(.disabled):hover) { - color: ${neutralFillStrongHover}; - } - - :host(:not(.disabled):active) { - color: ${neutralFillStrongActive}; - } - - :host(:${focusVisible}) { - ${focusTreatmentBase} - } - - :host::-moz-focus-inner { - border: 0; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host { - background: ${SystemColors.ButtonFace}; - border-color: ${SystemColors.ButtonText}; - } - :host .next, - :host .previous { - color: ${SystemColors.ButtonText}; - fill: currentcolor; - } - :host(:not(.disabled):hover) { - background: ${SystemColors.Highlight}; - } - :host(:not(.disabled):hover) .next, - :host(:not(.disabled):hover) .previous { - color: ${SystemColors.HighlightText}; - fill: currentcolor; - } - :host(.disabled) { - opacity: 1; - } - :host(.disabled), - :host(.disabled) .next, - :host(.disabled) .previous { - border-color: ${SystemColors.GrayText}; - color: ${SystemColors.GrayText}; - fill: currentcolor; - } - :host(:${focusVisible}) { - forced-color-adjust: none; - outline-color: ${SystemColors.Highlight}; - } - `, - ), - ); diff --git a/packages/web-components/src/flipper/flipper.vscode.definition.json b/packages/web-components/src/flipper/flipper.vscode.definition.json deleted file mode 100644 index c0193cef3815e..0000000000000 --- a/packages/web-components/src/flipper/flipper.vscode.definition.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-flipper", - "title": "Flipper", - "description": "The Fluent UI flipper element", - "attributes": [ - { - "name": "disabled", - "title": "Disabled", - "type": "boolean", - "description": "Sets the disabled state of the flipper", - "default": true, - "required": false - }, - { - "name": "aria-hidden", - "title": "ARIA hidden", - "type": "boolean", - "description": "Flippers are often a duplicate method of navigation, so by default they are hidden from assistive technology (AT). When set to true, the element is exposed to AT", - "default": true, - "required": false - }, - { - "name": "direction", - "type": "string", - "title": "Direction", - "description": "The navigation direction of the flipper", - "values": [ - { - "name": "previous" - }, - { - "name": "next" - } - ], - "default": "next", - "required": false - } - ], - "slots": [ - { - "name": "previous", - "title": "Previous slot", - "description": "Slot to provide a custom icon to represent the 'previous' flipper state" - }, - { - "name": "next", - "title": "Next slot", - "description": "Slot to provide a custom icon to represent the 'next' flipper state" - } - ] - } - ] -} diff --git a/packages/web-components/src/flipper/index.ts b/packages/web-components/src/flipper/index.ts deleted file mode 100644 index 964d5c4477637..0000000000000 --- a/packages/web-components/src/flipper/index.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Flipper, FlipperOptions, flipperTemplate as template } from '@microsoft/fast-foundation'; -import { flipperStyles as styles } from './flipper.styles'; - -/** - * The Fluent Flipper Element. Implements {@link @microsoft/fast-foundation#Flipper}, - * {@link @microsoft/fast-foundation#flipperTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentFlipper = Flipper.compose({ - baseName: 'flipper', - template, - styles, - next: ` - - - - `, - previous: ` - - - - `, -}); - -/** - * Styles for Flipper - * @public - */ -export const flipperStyles = styles; - -/** - * Base class for Flipper - * @public - */ -export { Flipper }; diff --git a/packages/web-components/src/fluent-design-system.ts b/packages/web-components/src/fluent-design-system.ts deleted file mode 100644 index e3cc70d05f44d..0000000000000 --- a/packages/web-components/src/fluent-design-system.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { DesignSystem } from '@microsoft/fast-foundation'; - -/** - * Provides a design system for the specified element either by returning one that was - * already created for that element or creating one. - * @param element - The element to root the design system at. By default, this is the body. - * @returns A Fluent Design System - * @public - */ -export function provideFluentDesignSystem(element?: HTMLElement): DesignSystem { - return DesignSystem.getOrCreate(element).withPrefix('fluent'); -} diff --git a/packages/web-components/src/horizontal-scroll/fixtures/horizontal-scroll.html b/packages/web-components/src/horizontal-scroll/fixtures/horizontal-scroll.html deleted file mode 100644 index a530704e1b891..0000000000000 --- a/packages/web-components/src/horizontal-scroll/fixtures/horizontal-scroll.html +++ /dev/null @@ -1,280 +0,0 @@ - -

Horizontal scroll

- - - - -

Default

- - - Card number 1 - A button - - - Card number 2 - A button - - - Card number 3 - A button - - - Card number 4 - A button - - - Card number 5 - A button - - - Card number 6 - A button - - - Card number 7 - A button - - - Card number 8 - A button - - - Card number 9 - A button - - - Card number 10 - A button - - - Card number 11 - A button - - - Card number 12 - A button - - - Card number 13 - A button - - - Card number 14 - A button - - - Card number 15 - A button - - - Card number 16 - A button - - - -

Delay loaded content

- - -

Full width cards

- - Card number 1 - Card number 2 - Card number 3 - Card number 4 - Card number 5 - Card number 6 - - -

Slow scroll (200 pixels/second)

- - Card number 1 - Card number 2 - Card number 3 - Card number 4 - Card number 5 - Card number 6 - Card number 7 - Card number 8 - Card number 9 - Card number 10 - Card number 11 - Card number 12 - Card number 13 - Card number 14 - Card number 15 - Card number 16 - - -

Right gradient

- - Card number 1 - Card number 2 - Card number 3 - Card number 4 - Card number 5 - Card number 6 - Card number 7 - Card number 8 - Card number 9 - Card number 10 - Card number 11 - Card number 12 - Card number 13 - Card number 14 - Card number 15 - Card number 16 - - -

Gradient both sides

- - Card number 1 - Card number 2 - Card number 3 - Card number 4 - Card number 5 - Card number 6 - Card number 7 - Card number 8 - Card number 9 - Card number 10 - Card number 11 - Card number 12 - Card number 13 - Card number 14 - Card number 15 - Card number 16 - - -

Varying heights and widths (default middle aligned)

- - Card number 1 - Card number 2 - Card number 3 - Card number 4 - Card number 5 - Card number 6 - Card number 7 - Card number 8 - Card number 9 - Card number 10 - Card number 11 - Card number 12 - Card number 13 - Card number 14 - Card number 15 - Card number 16 - - -

Top aligned

- - Card number 1 - Card number 2 - Card number 3 - Card number 4 - Card number 5 - Card number 6 - Card number 7 - Card number 8 - Card number 9 - Card number 10 - Card number 11 - Card number 12 - Card number 13 - Card number 14 - Card number 15 - Card number 16 - - -

Bottom aligned

- - Card number 1 - Card number 2 - Card number 3 - Card number 4 - Card number 5 - Card number 6 - Card number 7 - Card number 8 - Card number 9 - Card number 10 - Card number 11 - Card number 12 - Card number 13 - Card number 14 - Card number 15 - Card number 16 - - -

Mobile horizontal-scroll

- - Card number 1 - Card number 2 - Card number 3 - Card number 4 - Card number 5 - Card number 6 - Card number 7 - Card number 8 - Card number 9 - Card number 10 - Card number 11 - Card number 12 - Card number 13 - Card number 14 - Card number 15 - Card number 16 - diff --git a/packages/web-components/src/horizontal-scroll/horizontal-scroll.stories.ts b/packages/web-components/src/horizontal-scroll/horizontal-scroll.stories.ts deleted file mode 100644 index 051e1456d6a32..0000000000000 --- a/packages/web-components/src/horizontal-scroll/horizontal-scroll.stories.ts +++ /dev/null @@ -1,85 +0,0 @@ -import HorizontalScrollTemplate from './fixtures/horizontal-scroll.html'; -import './index'; - -export default { - title: 'Components/Horizontal Scroll', -}; - -export const HorizontalScroll = () => HorizontalScrollTemplate; - -const example = ` - - - Card number 1 - A button - - - Card number 2 - A button - - - Card number 3 - A button - - - Card number 4 - A button - - - Card number 5 - A button - - - Card number 6 - A button - - - Card number 7 - A button - - - Card number 8 - A button - - - Card number 9 - A button - - - Card number 10 - A button - - - Card number 11 - A button - - - Card number 12 - A button - - - Card number 13 - A button - - - Card number 14 - A button - - - Card number 15 - A button - - - Card number 16 - A button - - -`; - -HorizontalScroll.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/horizontal-scroll/horizontal-scroll.styles.ts b/packages/web-components/src/horizontal-scroll/horizontal-scroll.styles.ts deleted file mode 100644 index 66c70f0fde898..0000000000000 --- a/packages/web-components/src/horizontal-scroll/horizontal-scroll.styles.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { display, ElementDefinitionContext, HorizontalScrollOptions } from '@microsoft/fast-foundation'; -import { DirectionalStyleSheetBehavior } from '../styles'; - -const ltrActionsStyles = css` - .scroll-prev { - right: auto; - left: 0; - } - - .scroll.scroll-next::before, - .scroll-next .scroll-action { - left: auto; - right: 0; - } - - .scroll.scroll-next::before { - background: linear-gradient(to right, transparent, var(--scroll-fade-next)); - } - - .scroll-next .scroll-action { - transform: translate(50%, -50%); - } -`; - -const rtlActionsStyles = css` - .scroll.scroll-next { - right: auto; - left: 0; - } - - .scroll.scroll-next::before { - background: linear-gradient(to right, var(--scroll-fade-next), transparent); - left: auto; - right: 0; - } - - .scroll.scroll-prev::before { - background: linear-gradient(to right, transparent, var(--scroll-fade-previous)); - } - - .scroll-prev .scroll-action { - left: auto; - right: 0; - transform: translate(50%, -50%); - } -`; - -/** - * Styles used for the flipper container and gradient fade - * @public - */ -export const ActionsStyles = css` - .scroll-area { - position: relative; - } - - div.scroll-view { - overflow-x: hidden; - } - - .scroll { - bottom: 0; - pointer-events: none; - position: absolute; - right: 0; - top: 0; - user-select: none; - width: 100px; - } - - .scroll.disabled { - display: none; - } - - .scroll::before, - .scroll-action { - left: 0; - position: absolute; - } - - .scroll::before { - background: linear-gradient(to right, var(--scroll-fade-previous), transparent); - content: ''; - display: block; - height: 100%; - width: 100%; - } - - .scroll-action { - pointer-events: auto; - right: auto; - top: 50%; - transform: translate(-50%, -50%); - } - - ::slotted(fluent-flipper) { - opacity: 0; - transition: opacity 0.2s ease-in-out; - } - - .scroll-area:hover ::slotted(fluent-flipper) { - opacity: 1; - } -`.withBehaviors(new DirectionalStyleSheetBehavior(ltrActionsStyles, rtlActionsStyles)); - -/** - * Styles handling the scroll container and content - * @public - */ -export const horizontalScrollStyles: ( - context: ElementDefinitionContext, - definition: HorizontalScrollOptions, -) => ElementStyles = (context: ElementDefinitionContext, definition: HorizontalScrollOptions) => css` - ${display('block')} :host { - --scroll-align: center; - --scroll-item-spacing: 4px; - contain: layout; - position: relative; - } - - .scroll-view { - overflow-x: auto; - scrollbar-width: none; - } - - ::-webkit-scrollbar { - display: none; - } - - .content-container { - align-items: var(--scroll-align); - display: inline-flex; - flex-wrap: nowrap; - position: relative; - } - - .content-container ::slotted(*) { - margin-right: var(--scroll-item-spacing); - } - - .content-container ::slotted(*:last-child) { - margin-right: 0; - } -`; diff --git a/packages/web-components/src/horizontal-scroll/horizontal-scroll.vscode.definition.json b/packages/web-components/src/horizontal-scroll/horizontal-scroll.vscode.definition.json deleted file mode 100644 index 6d5ba3300b4f6..0000000000000 --- a/packages/web-components/src/horizontal-scroll/horizontal-scroll.vscode.definition.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-horizontal-scroll", - "title": "Horizontal Scroll", - "description": "The Fluent UI HorizontalScroll element", - "attributes": [ - { - "name": "view", - "title": "View", - "description": "Default or mobile view", - "type": "string", - "values": [ - { - "name": "mobile" - }, - { - "name": "default" - } - ], - "default": false, - "required": false - }, - { - "name": "speed", - "title": "Speed", - "description": "Scroll speed in pixels per second", - "type": "number", - "default": false, - "required": false - }, - { - "name": "easing", - "title": "Easing", - "description": "Scroll easing", - "type": "string", - "values": [ - { - "name": "linear" - }, - { - "name": "ease-in" - }, - { - "name": "ease-out" - }, - { - "name": "ease-in-out" - } - ], - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "previousFlipper", - "title": "Prevous flipper slot", - "description": "Flipper used to scroll to previous content" - }, - { - "name": "nextFlipper", - "title": "Next flipper slot", - "description": "Flipper used to scroll to next content" - }, - { - "name": "", - "title": "Default slot", - "description": "The child nodes to scroll through" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned above the horizontal-scroll" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned below the horizontal-scroll" - } - ] - } - ] -} diff --git a/packages/web-components/src/horizontal-scroll/index.ts b/packages/web-components/src/horizontal-scroll/index.ts deleted file mode 100644 index 8178dc1580bb8..0000000000000 --- a/packages/web-components/src/horizontal-scroll/index.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { html } from '@microsoft/fast-element'; -import { - HorizontalScroll as FoundationHorizontalScroll, - HorizontalScrollOptions, - horizontalScrollTemplate as template, -} from '@microsoft/fast-foundation'; -import { ActionsStyles, horizontalScrollStyles as styles } from './horizontal-scroll.styles'; - -/** - * @internal - */ -export class HorizontalScroll extends FoundationHorizontalScroll { - /** - * @public - */ - public connectedCallback(): void { - super.connectedCallback(); - - if (this.view !== 'mobile') { - this.$fastController.addStyles(ActionsStyles); - } - } -} - -/** - * The Fluent HorizontalScroll Element. Implements {@link @microsoft/fast-foundation#HorizontalScroll}, - * {@link @microsoft/fast-foundation#horizontalScrollTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentHorizontalScroll = HorizontalScroll.compose({ - baseName: 'horizontal-scroll', - baseClass: FoundationHorizontalScroll, - template, - styles, - nextFlipper: html` - - `, - previousFlipper: html` - - `, -}); - -/** - * Styles for horizontal scroll - * @public - */ -export const horizontalScrollStyles = styles; diff --git a/packages/web-components/src/index-rollup.ts b/packages/web-components/src/index-rollup.ts index cac979825bf9d..ea465c2a34a4e 100644 --- a/packages/web-components/src/index-rollup.ts +++ b/packages/web-components/src/index-rollup.ts @@ -1,16 +1 @@ -// TODO: Is exporting Foundation still necessary with the updated API's? -// export * from "@microsoft/fast-element"; -import { DesignToken } from '@microsoft/fast-foundation'; -import { allComponents } from './custom-elements'; -import { provideFluentDesignSystem } from './fluent-design-system'; - -export { DesignToken }; export * from './index'; - -/** - * The global Fluent Design System. - * @remarks - * Only available if the components are added through a script tag - * rather than a module/build system. - */ -export const FluentDesignSystem = provideFluentDesignSystem().register(allComponents); diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index 5a21173b106e1..7d394c507ef22 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -1,51 +1 @@ -/** - * Export all custom element definitions. - */ -export * from './custom-elements'; -export * from './fluent-design-system'; -export * from './accordion/'; -export * from './anchor/'; -export * from './anchored-region'; -export * from './badge/'; -export * from './breadcrumb'; -export * from './breadcrumb-item'; -export * from './button/'; -export * from './card/'; -export * from './checkbox/'; -export * from './combobox/'; -export * from './data-grid'; -export * from './design-system-provider/'; -export * from './dialog/'; -export * from './divider/'; -export * from './flipper/'; -export * from './horizontal-scroll/'; -export * from './listbox'; -export * from './listbox-option'; -export * from './menu/'; -export * from './menu-item/'; -export * from './number-field/'; -export * from './progress/'; -export * from './radio/'; -export * from './radio-group/'; -export * from './search/'; -export * from './select'; -export * from './skeleton/'; -export * from './slider/'; -export * from './slider-label/'; -export * from './switch/'; -export * from './tabs/'; -export * from './text-area/'; -export * from './text-field/'; -export * from './toolbar'; -export * from './tooltip'; -export * from './tree-item/'; -export * from './tree-view/'; - -// export styles and utils -export * from './design-tokens'; -export * from './styles'; -export { Palette, PaletteRGB } from './color/palette'; -export { InteractiveSwatchSet } from './color/recipe'; -export { Swatch, SwatchRGB } from './color/swatch'; -export { isDark } from './color/utilities/is-dark'; -export { StandardLuminance } from './color/utilities/base-layer-luminance'; +export const empty = ''; diff --git a/packages/web-components/src/listbox-option/fixtures/base.html b/packages/web-components/src/listbox-option/fixtures/base.html deleted file mode 100644 index 16a1c1ce37792..0000000000000 --- a/packages/web-components/src/listbox-option/fixtures/base.html +++ /dev/null @@ -1,31 +0,0 @@ -

Option

- -

Defaults

- Text content is the value when the value attribute is absent. - - - Even when the value attribute and text are both present, this text should be displayed. - - - - -

Disabled

-This option is disabled. - -

Selected

-This option is selected by default. - -

Slots

- - - - - - - - This option has an icon in its start and end slots. - diff --git a/packages/web-components/src/listbox-option/index.ts b/packages/web-components/src/listbox-option/index.ts deleted file mode 100644 index de73b557335ab..0000000000000 --- a/packages/web-components/src/listbox-option/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ListboxOption, listboxOptionTemplate as template } from '@microsoft/fast-foundation'; -import { optionStyles as styles } from './listbox-option.styles'; - -/** - * The Fluent option Custom Element. Implements {@link @microsoft/fast-foundation#ListboxOption} - * {@link @microsoft/fast-foundation#listboxOptionTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - * - */ -export const fluentOption = ListboxOption.compose({ - baseName: 'option', - template, - styles, -}); - -/** - * Styles for Option - * @public - */ -export const OptionStyles = styles; diff --git a/packages/web-components/src/listbox-option/listbox-option.stories.ts b/packages/web-components/src/listbox-option/listbox-option.stories.ts deleted file mode 100644 index e83e8bf56c14c..0000000000000 --- a/packages/web-components/src/listbox-option/listbox-option.stories.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { fluentOption } from './index'; - -export default { - title: 'Components/Listbox Option', - component: fluentOption, - argTypes: { - disabled: { - control: { type: 'boolean' }, - }, - selected: { - control: { type: 'boolean' }, - }, - value: { - control: { type: 'text' }, - }, - }, -}; - -const listBoxTemplate = ({ disabled, label, selected, value }) => ` - ${label} -`; - -export const ListboxOption = listBoxTemplate.bind({}); - -ListboxOption.args = { - label: 'This is an Option', - selected: false, -}; - -const example = ` - Text content is the value when the value attribute is absent. -`; - -ListboxOption.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/listbox-option/listbox-option.styles.ts b/packages/web-components/src/listbox-option/listbox-option.styles.ts deleted file mode 100644 index 80d20b6d4a33c..0000000000000 --- a/packages/web-components/src/listbox-option/listbox-option.styles.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - disabledCursor, - display, - ElementDefinitionContext, - focusVisible, - forcedColorsStylesheetBehavior, - FoundationElementDefinition, -} from '@microsoft/fast-foundation'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { heightNumber } from '../styles/size'; -import { - accentFillRest, - controlCornerRadius, - designUnit, - disabledOpacity, - focusStrokeWidth, - neutralFillSecondaryActive, - neutralFillSecondaryHover, - neutralFillSecondaryRest, - neutralFillStealthActive, - neutralFillStealthFocus, - neutralFillStealthHover, - neutralFillStealthRest, - neutralForegroundRest, - strokeWidth, -} from '../design-tokens'; -import { typeRampBase } from '../styles/patterns/type-ramp'; -import { focusTreatmentBase } from '../styles/focus'; -import { DirectionalStyleSheetBehavior } from '../styles/direction'; - -export const optionStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - ${display('inline-flex')} :host { - position: relative; - ${typeRampBase} - background: ${neutralFillStealthRest}; - border-radius: calc(${controlCornerRadius} * 1px); - border: calc(${strokeWidth} * 1px) solid transparent; - box-sizing: border-box; - color: ${neutralForegroundRest}; - cursor: pointer; - fill: currentcolor; - height: calc(${heightNumber} * 1px); - overflow: hidden; - align-items: center; - padding: 0 calc(((${designUnit} * 3) - ${strokeWidth} - 1) * 1px); - user-select: none; - white-space: nowrap; - } - - :host::before { - content: ''; - display: block; - position: absolute; - left: calc((${focusStrokeWidth} - ${strokeWidth}) * 1px); - top: calc((${heightNumber} / 4) - ${focusStrokeWidth} * 1px); - width: 3px; - height: calc((${heightNumber} / 2) * 1px); - background: transparent; - border-radius: calc(${controlCornerRadius} * 1px); - } - - :host(:not([disabled]):hover) { - background: ${neutralFillStealthHover}; - } - - :host(:not([disabled]):active) { - background: ${neutralFillStealthActive}; - } - - :host(:not([disabled]):active)::before { - background: ${accentFillRest}; - height: calc(((${heightNumber} / 2) - 6) * 1px); - } - - :host([aria-selected='true'])::before { - background: ${accentFillRest}; - } - - :host(:${focusVisible}) { - ${focusTreatmentBase} - background: ${neutralFillStealthFocus}; - } - - :host([aria-selected='true']) { - background: ${neutralFillSecondaryRest}; - } - - :host(:not([disabled])[aria-selected='true']:hover) { - background: ${neutralFillSecondaryHover}; - } - - :host(:not([disabled])[aria-selected='true']:active) { - background: ${neutralFillSecondaryActive}; - } - - :host(:not([disabled]):not([aria-selected='true']):hover) { - background: ${neutralFillStealthHover}; - } - - :host(:not([disabled]):not([aria-selected='true']):active) { - background: ${neutralFillStealthActive}; - } - - :host([disabled]) { - cursor: ${disabledCursor}; - opacity: ${disabledOpacity}; - } - - .content { - grid-column-start: 2; - justify-self: start; - overflow: hidden; - text-overflow: ellipsis; - } - - .start, - .end, - ::slotted(svg) { - display: flex; - } - - ::slotted([slot='end']) { - margin-inline-start: 1ch; - } - - ::slotted([slot='start']) { - margin-inline-end: 1ch; - } - `.withBehaviors( - new DirectionalStyleSheetBehavior(null, css` - :host::before { - right: calc((${focusStrokeWidth} - ${strokeWidth}) * 1px); - } - `), - forcedColorsStylesheetBehavior( - css` - :host { - background: ${SystemColors.ButtonFace}; - border-color: ${SystemColors.ButtonFace}; - color: ${SystemColors.ButtonText}; - } - :host(:not([disabled]):not([aria-selected="true"]):hover), - :host(:not([disabled])[aria-selected="true"]:hover), - :host([aria-selected="true"]) { - forced-color-adjust: none; - background: ${SystemColors.Highlight}; - color: ${SystemColors.HighlightText}; - } - :host(:not([disabled]):active)::before, - :host([aria-selected='true'])::before { - background: ${SystemColors.HighlightText}; - } - :host([disabled]), - :host([disabled]:not([aria-selected='true']):hover) { - background: ${SystemColors.Canvas}; - color: ${SystemColors.GrayText}; - fill: currentcolor; - opacity: 1; - } - :host(:${focusVisible}) { - outline-color: ${SystemColors.CanvasText}; - } - `, - ), - ); diff --git a/packages/web-components/src/listbox-option/listbox-option.vscode.definition.json b/packages/web-components/src/listbox-option/listbox-option.vscode.definition.json deleted file mode 100644 index b86e0b7400afb..0000000000000 --- a/packages/web-components/src/listbox-option/listbox-option.vscode.definition.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-option", - "title": "Option", - "description": "The Fluent UI option element", - "attributes": [ - { - "name": "disabled", - "title": "Disabled", - "type": "boolean", - "description": "Sets the disabled state of the option", - "default": false, - "required": false - }, - { - "name": "selected", - "title": "Selected", - "type": "boolean", - "description": "The selected state of the option", - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the option" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned before the option content" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the option content" - } - ] - } - ] -} diff --git a/packages/web-components/src/listbox/fixtures/base.html b/packages/web-components/src/listbox/fixtures/base.html deleted file mode 100644 index 3eab5a0285ccf..0000000000000 --- a/packages/web-components/src/listbox/fixtures/base.html +++ /dev/null @@ -1,62 +0,0 @@ -

Listbox

-

Default

- - This option has no value - This option is disabled - This option has a value - This option is selected by default - - -

Long list

- - Alabama - Alaska - Arizona - Arkansas - California - Colorado - Connecticut - Delaware - Florida - Georgia - Hawaii - Idaho - Illinois - Indiana - Iowa - Kansas - Kentucky - Louisiana - Maine - Maryland - Massachussets - Michigain - Minnesota - Mississippi - Missouri - Montana - Nebraska - Nevada - New Hampshire - New Jersey - New Mexico - New York - North Carolina - North Dakota - Ohio - Oklahoma - Oregon - Pennsylvania - Rhode Island - South Carolina - South Dakota - Texas - Tennessee - Utah - Vermont - Virginia - Washington - Wisconsin - West Virginia - Wyoming - diff --git a/packages/web-components/src/listbox/index.ts b/packages/web-components/src/listbox/index.ts deleted file mode 100644 index b6fc34c0a2f1a..0000000000000 --- a/packages/web-components/src/listbox/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Listbox as FoundationListboxElement, listboxTemplate as template } from '@microsoft/fast-foundation'; -import { listboxStyles as styles } from './listbox.styles'; - -export class Listbox extends FoundationListboxElement {} - -/** - * The Fluent listbox Custom Element. Implements, {@link @microsoft/fast-foundation#Listbox} - * {@link @microsoft/fast-foundation#listboxTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - * - */ -export const fluentListbox = Listbox.compose({ - baseName: 'listbox', - template, - styles, -}); - -/** - * Styles for Listbox - * @public - */ -export const listboxStyles = styles; diff --git a/packages/web-components/src/listbox/listbox.stories.ts b/packages/web-components/src/listbox/listbox.stories.ts deleted file mode 100644 index 68fb4ceccf7f1..0000000000000 --- a/packages/web-components/src/listbox/listbox.stories.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { fluentListbox } from './index'; - -export default { - title: 'Components/Listbox', - component: fluentListbox, -}; - -const listBoxTemplate = () => ` - - This option has no value - This option is disabled - This option has a value - This option is selected by default - -`; - -export const Listbox = listBoxTemplate.bind({}); - -const example = ` - - This option has no value - This option is disabled - This option has a value - This option is selected by default - -`; - -Listbox.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/listbox/listbox.styles.ts b/packages/web-components/src/listbox/listbox.styles.ts deleted file mode 100644 index 98ab211e32a9d..0000000000000 --- a/packages/web-components/src/listbox/listbox.styles.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - display, - ElementDefinitionContext, - FoundationElementDefinition, - ListboxOption -} from '@microsoft/fast-foundation'; -import { - controlCornerRadius, - designUnit, - neutralStrokeRest, - strokeWidth, -} from '../design-tokens'; -import { focusTreatmentBase } from '../styles/focus'; - -export const listboxStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - ${display('inline-flex')} :host { - border: calc(${strokeWidth} * 1px) solid ${neutralStrokeRest}; - border-radius: calc(${controlCornerRadius} * 1px); - box-sizing: border-box; - flex-direction: column; - padding: calc(${designUnit} * 1px) 0; - } - - ::slotted(${context.tagFor(ListboxOption)}) { - margin: 0 calc(${designUnit} * 1px); - } - - :host(:focus-within:not([disabled])) { - ${focusTreatmentBase} - } - ` diff --git a/packages/web-components/src/listbox/listbox.vscode.definition.json b/packages/web-components/src/listbox/listbox.vscode.definition.json deleted file mode 100644 index 8b4f3a9e197ba..0000000000000 --- a/packages/web-components/src/listbox/listbox.vscode.definition.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-listbox", - "title": "Listbox", - "description": "The Fluent UI listbox element", - "attributes": [ - { - "name": "role", - "title": "Role", - "description": "The ARIA role for the listbox", - "type": "string", - "default": "listbox", - "required": true, - "values": [ - { - "name": "listbox" - } - ] - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Sets the disabled state of the listbox", - "type": "boolean", - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "Supports fluent-option or option elements" - } - ] - } - ] -} diff --git a/packages/web-components/src/menu-item/README.md b/packages/web-components/src/menu-item/README.md deleted file mode 100644 index 955ea3baa0f50..0000000000000 --- a/packages/web-components/src/menu-item/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# fluent-menu-item - -The menu item is an element meant to be used with [menu](../menu/README.md). diff --git a/packages/web-components/src/menu-item/fixtures/menu-item.html b/packages/web-components/src/menu-item/fixtures/menu-item.html deleted file mode 100644 index 3ce672d55e59e..0000000000000 --- a/packages/web-components/src/menu-item/fixtures/menu-item.html +++ /dev/null @@ -1,75 +0,0 @@ -

Menu Item

- -

Default (menuitem)

-Menu item 1 - -

Disabled

-Menu item 1 - -

Disabled Start End

- - - - - Menu item 1 - - - - - -

menuitemcheckbox

-Menu item 1 - -
checked
-Menu item 1 - -

menuitemradio

-Menu item 1 - -
checked
-Menu item 1 - -

Start

- - - - - Menu item 1 - - -

End

- - Menu item 1 - - - - - -

Accelerator

- - Menu item 1 - Accelerator - - -

Complex content layout

- - - - - Menu item 1 - - - - diff --git a/packages/web-components/src/menu-item/index.ts b/packages/web-components/src/menu-item/index.ts deleted file mode 100644 index 87bffb4df5559..0000000000000 --- a/packages/web-components/src/menu-item/index.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { MenuItem, MenuItemOptions, menuItemTemplate as template } from '@microsoft/fast-foundation'; -import { menuItemStyles as styles } from './menu-item.styles'; - -/** - * The Fluent Menu Item Element. Implements {@link @microsoft/fast-foundation#MenuItem}, - * {@link @microsoft/fast-foundation#menuItemTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentMenuItem = MenuItem.compose({ - baseName: 'menu-item', - template, - styles, - checkboxIndicator: ` - - - - `, - expandCollapseGlyph: ` - - - - `, - radioIndicator: ` - - - - `, -}); - -/** - * Styles for MenuItem - * @public - */ -export const menuItemStyles = styles; - -/** - * Menu item base class - * @public - */ -export { MenuItem }; diff --git a/packages/web-components/src/menu-item/menu-item.stories.ts b/packages/web-components/src/menu-item/menu-item.stories.ts deleted file mode 100644 index ad0dda4865485..0000000000000 --- a/packages/web-components/src/menu-item/menu-item.stories.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { fluentMenuItem } from './index'; - -export default { - title: 'Components/Menu Item', - component: fluentMenuItem, - argTypes: { - checked: { - control: { type: 'boolean' }, - }, - disabled: { - control: { type: 'boolean' }, - }, - }, -}; - -const MenuItemTemplate = ({ checked, disabled }) => ` - Menu item 1 -`; - -export const MenuItem = MenuItemTemplate.bind({}); - -MenuItem.args = { - disabled: false, - checked: false, -}; - -const example = ` -Menu item -`; - -MenuItem.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/menu-item/menu-item.styles.ts b/packages/web-components/src/menu-item/menu-item.styles.ts deleted file mode 100644 index 851fab9348f5a..0000000000000 --- a/packages/web-components/src/menu-item/menu-item.styles.ts +++ /dev/null @@ -1,293 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - disabledCursor, - display, - ElementDefinitionContext, - focusVisible, - forcedColorsStylesheetBehavior, - MenuItemOptions, -} from '@microsoft/fast-foundation'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { DirectionalStyleSheetBehavior, heightNumber } from '../styles/index'; -import { - controlCornerRadius, - disabledOpacity, - neutralFillStealthActive, - neutralFillStealthHover, - neutralForegroundHint, - neutralForegroundRest, - strokeWidth, -} from '../design-tokens'; -import { typeRampBase } from '../styles/patterns/type-ramp'; -import { focusTreatmentBase } from '../styles/focus'; - -export const menuItemStyles: (context: ElementDefinitionContext, definition: MenuItemOptions) => ElementStyles = ( - context: ElementDefinitionContext, - definition: MenuItemOptions, -) => - css` - ${display('grid')} :host { - contain: layout; - overflow: visible; - ${typeRampBase} - box-sizing: border-box; - height: calc(${heightNumber} * 1px); - grid-template-columns: minmax(32px, auto) 1fr minmax(32px, auto); - grid-template-rows: auto; - justify-items: center; - align-items: center; - padding: 0; - white-space: nowrap; - color: ${neutralForegroundRest}; - fill: currentcolor; - cursor: pointer; - border-radius: calc(${controlCornerRadius} * 1px); - border: calc(${strokeWidth} * 1px) solid transparent; - position: relative; - } - - :host(.indent-0) { - grid-template-columns: auto 1fr minmax(32px, auto); - } - - :host(.indent-0) .content { - grid-column: 1; - grid-row: 1; - margin-inline-start: 10px; - } - - :host(.indent-0) .expand-collapse-glyph-container { - grid-column: 5; - grid-row: 1; - } - - :host(.indent-2) { - grid-template-columns: minmax(32px, auto) minmax(32px, auto) 1fr minmax(32px, auto) minmax(32px, auto); - } - - :host(.indent-2) .content { - grid-column: 3; - grid-row: 1; - margin-inline-start: 10px; - } - - :host(.indent-2) .expand-collapse-glyph-container { - grid-column: 5; - grid-row: 1; - } - - :host(.indent-2) .start { - grid-column: 2; - } - - :host(.indent-2) .end { - grid-column: 4; - } - - :host(:${focusVisible}) { - ${focusTreatmentBase} - } - - :host(:not([disabled]):hover) { - background: ${neutralFillStealthHover}; - } - - :host(:not([disabled]):active), - :host(.expanded) { - background: ${neutralFillStealthActive}; - color: ${neutralForegroundRest}; - z-index: 2; - } - - :host([disabled]) { - cursor: ${disabledCursor}; - opacity: ${disabledOpacity}; - } - - .content { - grid-column-start: 2; - justify-self: start; - overflow: hidden; - text-overflow: ellipsis; - } - - .start, - .end { - display: flex; - justify-content: center; - } - - :host(.indent-0[aria-haspopup='menu']) { - display: grid; - grid-template-columns: minmax(32px, auto) auto 1fr minmax(32px, auto) minmax(32px, auto); - align-items: center; - min-height: 32px; - } - - :host(.indent-1[aria-haspopup='menu']), - :host(.indent-1[role='menuitemcheckbox']), - :host(.indent-1[role='menuitemradio']) { - display: grid; - grid-template-columns: minmax(32px, auto) auto 1fr minmax(32px, auto) minmax(32px, auto); - align-items: center; - min-height: 32px; - } - - :host(.indent-2:not([aria-haspopup='menu'])) .end { - grid-column: 5; - } - - :host .input-container, - :host .expand-collapse-glyph-container { - display: none; - } - - :host([aria-haspopup='menu']) .expand-collapse-glyph-container, - :host([role='menuitemcheckbox']) .input-container, - :host([role='menuitemradio']) .input-container { - display: grid; - } - - :host([aria-haspopup='menu']) .content, - :host([role='menuitemcheckbox']) .content, - :host([role='menuitemradio']) .content { - grid-column-start: 3; - } - - :host([aria-haspopup='menu'].indent-0) .content { - grid-column-start: 1; - } - - :host([aria-haspopup='menu']) .end, - :host([role='menuitemcheckbox']) .end, - :host([role='menuitemradio']) .end { - grid-column-start: 4; - } - - :host .expand-collapse, - :host .checkbox, - :host .radio { - display: flex; - align-items: center; - justify-content: center; - position: relative; - box-sizing: border-box; - } - - :host .checkbox-indicator, - :host .radio-indicator, - slot[name='checkbox-indicator'], - slot[name='radio-indicator'] { - display: none; - } - - ::slotted([slot='end']:not(svg)) { - margin-inline-end: 10px; - color: ${neutralForegroundHint}; - } - - :host([aria-checked='true']) .checkbox-indicator, - :host([aria-checked='true']) slot[name='checkbox-indicator'], - :host([aria-checked='true']) .radio-indicator, - :host([aria-checked='true']) slot[name='radio-indicator'] { - display: flex; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host, - ::slotted([slot='end']:not(svg)) { - forced-color-adjust: none; - color: ${SystemColors.ButtonText}; - fill: currentcolor; - } - :host(:not([disabled]):hover) { - background: ${SystemColors.Highlight}; - color: ${SystemColors.HighlightText}; - fill: currentcolor; - } - :host(:hover) .start, - :host(:hover) .end, - :host(:hover)::slotted(svg), - :host(:active) .start, - :host(:active) .end, - :host(:active)::slotted(svg), - :host(:hover) ::slotted([slot='end']:not(svg)), - :host(:${focusVisible}) ::slotted([slot='end']:not(svg)) { - color: ${SystemColors.HighlightText}; - fill: currentcolor; - } - :host(.expanded) { - background: ${SystemColors.Highlight}; - color: ${SystemColors.HighlightText}; - } - :host(:${focusVisible}) { - background: ${SystemColors.Highlight}; - outline-color: ${SystemColors.ButtonText}; - color: ${SystemColors.HighlightText}; - fill: currentcolor; - } - :host([disabled]), - :host([disabled]:hover), - :host([disabled]:hover) .start, - :host([disabled]:hover) .end, - :host([disabled]:hover)::slotted(svg), - :host([disabled]:${focusVisible}) { - background: ${SystemColors.ButtonFace}; - color: ${SystemColors.GrayText}; - fill: currentcolor; - opacity: 1; - } - :host([disabled]:${focusVisible}) { - outline-color: ${SystemColors.GrayText}; - } - :host .expanded-toggle, - :host .checkbox, - :host .radio { - border-color: ${SystemColors.ButtonText}; - background: ${SystemColors.HighlightText}; - } - :host([checked]) .checkbox, - :host([checked]) .radio { - background: ${SystemColors.HighlightText}; - border-color: ${SystemColors.HighlightText}; - } - :host(:hover) .expanded-toggle, - :host(:hover) .checkbox, - :host(:hover) .radio, - :host(:${focusVisible}) .expanded-toggle, - :host(:${focusVisible}) .checkbox, - :host(:${focusVisible}) .radio, - :host([checked]:hover) .checkbox, - :host([checked]:hover) .radio, - :host([checked]:${focusVisible}) .checkbox, - :host([checked]:${focusVisible}) .radio { - border-color: ${SystemColors.HighlightText}; - } - :host([aria-checked='true']) { - background: ${SystemColors.Highlight}; - color: ${SystemColors.HighlightText}; - } - :host([aria-checked='true']) .checkbox-indicator, - :host([aria-checked='true']) ::slotted([slot='checkbox-indicator']), - :host([aria-checked='true']) ::slotted([slot='radio-indicator']) { - fill: ${SystemColors.Highlight}; - } - :host([aria-checked='true']) .radio-indicator { - background: ${SystemColors.Highlight}; - } - `, - ), - new DirectionalStyleSheetBehavior( - css` - .expand-collapse-glyph-container { - transform: rotate(0deg); - } - `, - css` - .expand-collapse-glyph-container { - transform: rotate(180deg); - } - `, - ), - ); diff --git a/packages/web-components/src/menu-item/menu-item.vscode.definition.json b/packages/web-components/src/menu-item/menu-item.vscode.definition.json deleted file mode 100644 index dbc6dcdcba846..0000000000000 --- a/packages/web-components/src/menu-item/menu-item.vscode.definition.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-menu-item", - "title": "Menu item", - "description": "The Fluent UI menu item element", - "attributes": [ - { - "name": "disabled", - "title": "Disabled", - "type": "boolean", - "description": "Sets the disabled state of the item", - "default": true, - "required": false - }, - { - "name": "expanded", - "title": "Expanded", - "type": "boolean", - "description": "The expanded state of the item", - "default": true, - "required": false - }, - { - "name": "role", - "title": "Role", - "type": "string", - "description": "The ARIA role of the menu item", - "default": "menuitem", - "values": [{ "name": "menuitem" }, { "name": "menuitemcheckbox" }, { "name": "menuitemradio" }], - "required": false - }, - { - "name": "checked", - "title": "Checked", - "type": "boolean", - "description": "The checked state for elements with a role of menuitemradio or menuitemcheckbox", - "default": true, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the menu item" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned before the item content" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the item content" - }, - { - "name": "submenu", - "title": "Sub menu slot", - "description": "The submenu slot" - }, - { - "name": "checkbox-indicator", - "title": "Checkbox indicator", - "description": "The checkbox indicator slot" - }, - { - "name": "radio-indicator", - "title": "Radio indicator", - "description": "The radio indicator slot" - }, - { - "name": "expand-collapse-indicator", - "title": "Expand/collapse indicator", - "description": "The expand/collapse indicator slot" - } - ] - } - ] -} diff --git a/packages/web-components/src/menu/README.md b/packages/web-components/src/menu/README.md deleted file mode 100644 index 817213738eb6d..0000000000000 --- a/packages/web-components/src/menu/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# fluent-menu - -The menu is a widget that offers a list of choices to the user, such as a set of actions or functions. diff --git a/packages/web-components/src/menu/fixtures/menu.html b/packages/web-components/src/menu/fixtures/menu.html deleted file mode 100644 index 1632d171f3cbf..0000000000000 --- a/packages/web-components/src/menu/fixtures/menu.html +++ /dev/null @@ -1,192 +0,0 @@ -

Menu

-

Default

- - Menu item 1 - Menu item 2 - Menu item 3 - - Menu item 4 -
Shortcut text
-
-
- -

With start, end and nested submenus

- - Menu item 1 - Menu item 2 - Menu item 3 - - - - - Menu item 4 - - - - - Checkbox 1 - Nested Menu item 1.1 - Nested Menu item 1.2 - Nested Menu item 1.3 - - - - -

With start, end slot with text and nested submenus

- - Menu item 1 - - Menu item 2 -
Shortcut text
-
- Menu item 3 - - - - - Menu item 4 -
Shortcut text
- - Checkbox 1 - Nested Menu item 1.1 - Nested Menu item 1.2 - Nested Menu item 1.3 - -
-
- -

With seperator

- - Menu item 1 - Menu item 2 -
- Menu item 3 - - - - - Menu item 4 - - - - -
- -

With nested submenus

- - - - - - Menu item 1 (checkbox) - - - - - - Menu item 2 - - Checkbox 1 - Nested Menu item 2.1 - Nested Menu item 2.2 - Nested Menu item 2.3 - - - - - - - Menu item 3 -
Shortcut text
-
- - Menu item 4 - - Nested Menu item 4.1 - Nested Menu item 4.2 - Nested Menu item 4.3 - - - - Menu item 5 - - Checkbox 1 - - Nested Menu item 5.1 - - Checkbox 1 - Nested Menu item 5.1.1 - Nested Menu item 5.1.2 - Nested Menu item 5.1.3 - - - - Nested Menu item 5.2 - - Nested Menu item 5.2.1 - Nested Menu item 5.2.2 - Nested Menu item 5.2.3 - - - - Nested Menu item 5.3 - - Nested Menu item 5.3.1 - Nested Menu item 5.3.2 - Nested Menu item 5.3.3 - - - - -
- -

With standard elements

- -
Menu item 1
-
Menu item 2
-
Menu item 3
-
- -

With fluent buttons and anchors

- - Menu item 1 - Menu item 2 - - Menu item 3 - - - Menu item 4 - - - -

With radio buttons and checkboxes

- - Menu item 1 - Menu item 2 - Menu item 3 - - Checkbox 1 - Checkbox 2 - - Radio 1.1 - Radio 1.2 - - Radio 2.1 - Radio 2.2 - diff --git a/packages/web-components/src/menu/index.ts b/packages/web-components/src/menu/index.ts deleted file mode 100644 index cfe6cef0de3e1..0000000000000 --- a/packages/web-components/src/menu/index.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Menu as FoundationMenu, menuTemplate as template } from '@microsoft/fast-foundation'; -import { fillColor, neutralLayerFloating } from '../design-tokens'; -import { menuStyles as styles } from './menu.styles'; - -/** - * The Fluent menu class - * @public - */ -export class Menu extends FoundationMenu { - /** - * @internal - */ - public connectedCallback(): void { - super.connectedCallback(); - - fillColor.setValueFor(this, neutralLayerFloating); - } -} - -/** - * The Fluent Menu Element. Implements {@link @microsoft/fast-foundation#Menu}, - * {@link @microsoft/fast-foundation#menuTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentMenu = Menu.compose({ - baseName: 'menu', - baseClass: FoundationMenu, - template, - styles, -}); - -/** - * Styles for Menu - * @public - */ -export const menuStyles = styles; diff --git a/packages/web-components/src/menu/menu.stories.ts b/packages/web-components/src/menu/menu.stories.ts deleted file mode 100644 index 119a586e6c9ba..0000000000000 --- a/packages/web-components/src/menu/menu.stories.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { fluentMenu } from './index'; - -export default { - title: 'Components/Menu', - component: fluentMenu, -}; - -const MenuTemplate = () => ` - - Menu item 1 - - Menu item 2 - - Nested Menu item 2.1 - - Nested Menu item 2.2 - - Nested Menu item 2.2.1 - Nested Menu item 2.2.2 - Nested Menu item 2.2.3 - - - Nested Menu item 2.3 - - - Menu item 3 - - Menu item 4 -
Shortcut text
-
-
-`; - -export const Menu = MenuTemplate.bind({}); - -const example = ` - - Menu item 1 - - Menu item 2 - - Nested Menu item 2.1 - Nested Menu item 2.2 - Nested Menu item 2.3 - - - Menu item 3 - - Menu item 4 -
Shortcut text
-
-
-`; - -Menu.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/menu/menu.styles.ts b/packages/web-components/src/menu/menu.styles.ts deleted file mode 100644 index 2935999cf06bb..0000000000000 --- a/packages/web-components/src/menu/menu.styles.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { display, Divider, ElementDefinitionContext, forcedColorsStylesheetBehavior, FoundationElementDefinition, MenuItem } from '@microsoft/fast-foundation'; -import { SystemColors } from "@microsoft/fast-web-utilities"; -import { elevationShadowFlyout } from '../styles/index'; -import { - designUnit, - layerCornerRadius, - neutralLayerFloating, - neutralStrokeDividerRest, - strokeWidth, -} from '../design-tokens'; - -export const menuStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - ${display('block')} :host { - background: ${neutralLayerFloating}; - border: calc(${strokeWidth} * 1px) solid transparent; - border-radius: calc(${layerCornerRadius} * 1px); - box-shadow: ${elevationShadowFlyout}; - padding: calc((${designUnit} - ${strokeWidth}) * 1px) 0; - max-width: 368px; - min-width: 64px; - } - - :host([slot='submenu']) { - width: max-content; - margin: 0 calc(${designUnit} * 2px); - } - - ::slotted(${context.tagFor(MenuItem)}) { - margin: 0 calc(${designUnit} * 1px); - } - - ::slotted(${context.tagFor(Divider)}) { - margin: calc(${designUnit} * 1px) 0; - } - - ::slotted(hr) { - box-sizing: content-box; - height: 0; - margin: calc(${designUnit} * 1px) 0; - border: none; - border-top: calc(${strokeWidth} * 1px) solid ${neutralStrokeDividerRest}; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host([slot='submenu']) { - background: ${SystemColors.Canvas}; - border-color: ${SystemColors.CanvasText}; - } - ` - ), - ); diff --git a/packages/web-components/src/menu/menu.vscode.definition.json b/packages/web-components/src/menu/menu.vscode.definition.json deleted file mode 100644 index e94794b447392..0000000000000 --- a/packages/web-components/src/menu/menu.vscode.definition.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-menu", - "title": "Menu", - "description": "The Fluent UI menu element", - "attributes": [], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "Supports fluent-menu-item elements or elements with a role of 'menuitem', 'menuitemcheckbox', and 'menuitemradio'" - } - ] - } - ] -} diff --git a/packages/web-components/src/number-field/fixtures/number-field.html b/packages/web-components/src/number-field/fixtures/number-field.html deleted file mode 100644 index 0e32828239cfe..0000000000000 --- a/packages/web-components/src/number-field/fixtures/number-field.html +++ /dev/null @@ -1,109 +0,0 @@ -

Number field

-

Default

- -Label - -

Hide step

-Label - -

With value

- - -

With min 1 and max 10

- - -

0.1 stepping

- - -

Full Width

- - -

Placeholder

- - - -

Required

- - - -

Disabled

- -label - - - -

Read only

- -label - - -

Autofocus

-autofocus - - -

Maxlength

-maxlength - - -

Minlength

-minlength - - -

With start

- - - - - - - -

With end

- - - - - - -

Filled

-
Default
- -label - -
Placeholder
- - - -
Required
- - - -
Disabled
- -label - - - -
Read only
- - label - - -

Visual vs audio label

- - Visible label - - - -

With aria-label

- - -
- -

In a form

- - -
diff --git a/packages/web-components/src/number-field/index.ts b/packages/web-components/src/number-field/index.ts deleted file mode 100644 index 3d0bc3559b8ac..0000000000000 --- a/packages/web-components/src/number-field/index.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { attr } from '@microsoft/fast-element'; -import { - NumberField as FoundationNumberField, - NumberFieldOptions, - numberFieldTemplate as template, -} from '@microsoft/fast-foundation'; -import { numberFieldStyles as styles } from './number-field.styles'; - -/** - * Number field appearances - * @public - */ -export type NumberFieldAppearance = 'filled' | 'outline'; - -/** - * The Fluent number field class - * @internal - */ -export class NumberField extends FoundationNumberField { - /** - * The appearance of the element. - * - * @public - * @remarks - * HTML Attribute: appearance - */ - @attr - public appearance: NumberFieldAppearance; - - /** - * @internal - */ - public connectedCallback() { - super.connectedCallback(); - - if (!this.appearance) { - this.appearance = 'outline'; - } - } -} - -/** - * Styles for NumberField - * @public - */ -export const numberFieldStyles = styles; - -/** - * The Fluent Number Field Custom Element. Implements {@link @microsoft/fast-foundation#NumberField}, - * {@link @microsoft/fast-foundation#numberFieldTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - * - * {@link https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus | delegatesFocus} - */ -export const fluentNumberField = NumberField.compose({ - baseName: 'number-field', - baseClass: FoundationNumberField, - styles, - template, - shadowOptions: { - delegatesFocus: true, - }, - stepDownGlyph: ` - - - - `, - stepUpGlyph: ` - - - -`, -}); diff --git a/packages/web-components/src/number-field/number-field.stories.ts b/packages/web-components/src/number-field/number-field.stories.ts deleted file mode 100644 index a141b828e3a4b..0000000000000 --- a/packages/web-components/src/number-field/number-field.stories.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { fluentNumberField } from './index'; - -export default { - title: 'Components/Number Field', - component: fluentNumberField, - argTypes: { - appearance: { - defaultValue: 'outline', - options: ['filled', 'outline'], - control: { type: 'radio' }, - }, - autoFocus: { - control: { type: 'boolean' }, - }, - disabled: { - control: { type: 'boolean' }, - }, - hideStep: { - control: { type: 'boolean' }, - }, - maxlength: { - control: { type: 'number' }, - }, - minlength: { - control: { type: 'number' }, - }, - placeholder: { - control: { type: 'text' }, - }, - readonly: { - control: { type: 'boolean' }, - }, - required: { - control: { type: 'boolean' }, - }, - step: { - control: { type: 'number' }, - defaultValue: 1, - }, - size: { - control: { type: 'number' }, - }, - value: { - control: { type: 'text' }, - }, - }, -}; - -const NumberFieldTemplate = ({ - appearance, - autoFocus, - disabled, - hideStep, - label, - maxlength, - minlength, - placeholder, - readonly, - required, - size, - step, - value, -}) => ` - - ${label ? `${label}` : ''} - -`; - -export const NumberField = NumberFieldTemplate.bind({}); - -NumberField.args = { - placeholder: 'type a number', - autoFocus: false, - disabled: false, - hideStep: false, - readonly: false, - required: false, -}; - -const example = ` - -`; - -NumberField.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/number-field/number-field.styles.ts b/packages/web-components/src/number-field/number-field.styles.ts deleted file mode 100644 index 7428062cc3147..0000000000000 --- a/packages/web-components/src/number-field/number-field.styles.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - display, - ElementDefinitionContext, - forcedColorsStylesheetBehavior, - NumberFieldOptions, -} from '@microsoft/fast-foundation'; -import { - baseInputStyles, - inputFilledStyles, - inputForcedColorStyles, - inputOutlineStyles, - inputStateStyles, -} from '../styles/index'; -import { appearanceBehavior } from '../utilities/behaviors'; -import { designUnit } from '../design-tokens'; - -const logicalControlSelector: string = '.root'; - -export const numberFieldStyles: (context: ElementDefinitionContext, definition: NumberFieldOptions) => ElementStyles = ( - context: ElementDefinitionContext, - definition: NumberFieldOptions, -) => - css` - ${display('inline-block')} - - ${baseInputStyles(context, definition, logicalControlSelector)} - - ${inputStateStyles(context, definition, logicalControlSelector)} - - .root { - display: flex; - flex-direction: row; - } - - .control { - -webkit-appearance: none; - color: inherit; - background: transparent; - border: 0; - height: calc(100% - 4px); - margin-top: auto; - margin-bottom: auto; - padding: 0 calc(${designUnit} * 2px + 1px); - font-family: inherit; - font-size: inherit; - line-height: inherit; - } - - .start, - .end { - margin: auto; - fill: currentcolor; - } - - .start { - display: flex; - margin-inline-start: 11px; - } - - .end { - display: flex; - margin-inline-end: 11px; - } - - .controls { - opacity: 0; - position: relative; - top: -1px; - z-index: 3; - } - - :host(:hover:not([disabled])) .controls, - :host(:focus-within:not([disabled])) .controls { - opacity: 1; - } - - .step-up, - .step-down { - display: flex; - padding: 0 8px; - cursor: pointer; - } - - .step-up { - padding-top: 3px; - } - `.withBehaviors( - appearanceBehavior('outline', inputOutlineStyles(context, definition, logicalControlSelector)), - appearanceBehavior('filled', inputFilledStyles(context, definition, logicalControlSelector)), - forcedColorsStylesheetBehavior(inputForcedColorStyles(context, definition, logicalControlSelector)), - ); diff --git a/packages/web-components/src/number-field/number-field.vscode.definition.json b/packages/web-components/src/number-field/number-field.vscode.definition.json deleted file mode 100644 index 0f7f0390dc07a..0000000000000 --- a/packages/web-components/src/number-field/number-field.vscode.definition.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-number-field", - "title": "Number field", - "description": "The Fluent UI number-field element", - "attributes": [ - { - "name": "appearance", - "title": "Appearance", - "description": "The number field's visual treatment", - "type": "string", - "values": [ - { - "name": "filled" - }, - { - "name": "outline" - } - ], - "default": "outline", - "required": false - }, - { - "name": "value", - "title": "Value", - "description": "The HTML value attribute of the number field", - "required": false, - "type": "string" - }, - { - "name": "appearance", - "title": "Appearance", - "description": "The number field's visual treatment", - "default": "outline", - "values": [{ "name": "outline" }, { "name": "filled" }], - "type": "string", - "required": false - }, - { - "name": "autofocus", - "title": "Autofocus", - "description": "Determines if the element should receive document focus on page load", - "required": false, - "type": "boolean", - "default": false - }, - { - "name": "placeholder", - "title": "Placeholder", - "description": "Sets the placeholder value of the element, generally used to provide a hint to the user", - "required": false, - "type": "string" - }, - { - "name": "list", - "title": "List ID", - "description": "Allows associating a datalist to the component", - "required": false, - "type": "string", - "default": "" - }, - { - "name": "maxlength", - "title": "Maximum length", - "description": "The maximum number of characters a user can enter", - "required": false, - "type": "number" - }, - { - "name": "minlength", - "title": "Minimum length", - "description": "The minimum number of characters a user can enter", - "required": false, - "type": "number" - }, - { - "name": "size", - "title": "Size", - "description": "Sets the width of the element to a specified number of characters", - "required": false, - "type": "number" - }, - { - "name": "name", - "title": "Name", - "description": "This element's value will be surfaced during form submission under the provided name", - "type": "string", - "default": "" - }, - { - "name": "required", - "title": "Required", - "description": "Require the field to be completed prior to form submission", - "type": "boolean", - "default": false - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Sets the disabled state of the text field", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "hide-step", - "title": "Hide step", - "description": "Hides the step controls", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "readonly", - "title": "Readonly", - "description": "When true, the control will be immutable by user interaction", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "max", - "title": "Maximum", - "description": "The maximum value", - "type": "string", - "default": false, - "required": false - }, - { - "name": "min", - "title": "Minimum", - "description": "The minimum value", - "type": "string", - "default": false, - "required": false - }, - { - "name": "step", - "title": "Increment", - "description": "Amount to increment or decrement the value by", - "type": "string", - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the number field represents its visual label" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned before the option content" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the option content" - } - ] - } - ] -} diff --git a/packages/web-components/src/progress/index.ts b/packages/web-components/src/progress/index.ts deleted file mode 100644 index e3760f8474573..0000000000000 --- a/packages/web-components/src/progress/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './progress/'; -export * from './progress-ring/'; diff --git a/packages/web-components/src/progress/progress-ring/fixtures/circular.html b/packages/web-components/src/progress/progress-ring/fixtures/circular.html deleted file mode 100644 index 34ac240801467..0000000000000 --- a/packages/web-components/src/progress/progress-ring/fixtures/circular.html +++ /dev/null @@ -1,22 +0,0 @@ -

Progress ring

-

Default

- - -

Paused

- - -

Custom Sizes

-
- - - - - -
-
- - - - - -
diff --git a/packages/web-components/src/progress/progress-ring/index.ts b/packages/web-components/src/progress/progress-ring/index.ts deleted file mode 100644 index 40da9fd10a44b..0000000000000 --- a/packages/web-components/src/progress/progress-ring/index.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { BaseProgress, ProgressRingOptions, progressRingTemplate as template } from '@microsoft/fast-foundation'; -import { progressRingStyles as styles } from './progress-ring.styles'; - -/** - * Progress Ring base class - * @public - */ -export class ProgressRing extends BaseProgress {} - -/** - * The Fluent Progress Ring Element. Implements {@link @microsoft/fast-foundation#BaseProgress}, - * {@link @microsoft/fast-foundation#progressRingTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentProgressRing = ProgressRing.compose({ - baseName: 'progress-ring', - template, - styles, - indeterminateIndicator: ` - - - - - `, -}); - -/** - * Styles for ProgressRing - * @public - */ -export const progressRingStyles = styles; diff --git a/packages/web-components/src/progress/progress-ring/progress-ring.stories.ts b/packages/web-components/src/progress/progress-ring/progress-ring.stories.ts deleted file mode 100644 index a9f66469ed8f8..0000000000000 --- a/packages/web-components/src/progress/progress-ring/progress-ring.stories.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { fluentProgressRing } from './index'; - -export default { - title: 'Components/Progress Ring', - component: fluentProgressRing, - argTypes: { - paused: { - control: { type: 'boolean' }, - }, - }, -}; - -const ProgressRingTemplate = ({ paused, value }) => ` - -`; - -export const ProgressRing = ProgressRingTemplate.bind({}); - -ProgressRing.args = { - paused: false, - value: 65, -}; - -const defaultExample = ` - -`; - -ProgressRing.parameters = { - docs: { - source: { - code: defaultExample, - }, - }, -}; - -export const ProgressRingAnimated = ProgressRingTemplate.bind({}); - -ProgressRingAnimated.args = { - paused: false, -}; - -export const ProgressRingPaused = ProgressRingTemplate.bind({}); - -ProgressRingPaused.args = { - paused: true, -}; - -const animatedExample = ` - -`; - -const pausedExample = ` - -`; - -ProgressRingAnimated.parameters = { - docs: { - source: { - code: animatedExample, - }, - }, -}; - -ProgressRingPaused.parameters = { - docs: { - source: { - code: pausedExample, - }, - }, -}; diff --git a/packages/web-components/src/progress/progress-ring/progress-ring.styles.ts b/packages/web-components/src/progress/progress-ring/progress-ring.styles.ts deleted file mode 100644 index a42897c1f3ad2..0000000000000 --- a/packages/web-components/src/progress/progress-ring/progress-ring.styles.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { - display, - ElementDefinitionContext, - forcedColorsStylesheetBehavior, - ProgressRingOptions, -} from '@microsoft/fast-foundation'; -import { heightNumber } from '../../styles'; -import { accentFillRest, neutralForegroundHint } from '../../design-tokens'; - -export const progressRingStyles: ( - context: ElementDefinitionContext, - definition: ProgressRingOptions, -) => ElementStyles = (context: ElementDefinitionContext, definition: ProgressRingOptions) => - css` - ${display('flex')} :host { - align-items: center; - height: calc(${heightNumber} * 1px); - width: calc(${heightNumber} * 1px); - } - - .progress { - height: 100%; - width: 100%; - } - - .background { - fill: none; - stroke-width: 2px; - } - - .determinate { - stroke: ${accentFillRest}; - fill: none; - stroke-width: 2px; - stroke-linecap: round; - transform-origin: 50% 50%; - transform: rotate(-90deg); - transition: all 0.2s ease-in-out; - } - - .indeterminate-indicator-1 { - stroke: ${accentFillRest}; - fill: none; - stroke-width: 2px; - stroke-linecap: round; - transform-origin: 50% 50%; - transform: rotate(-90deg); - transition: all 0.2s ease-in-out; - animation: spin-infinite 2s linear infinite; - } - - :host(.paused) .indeterminate-indicator-1 { - animation: none; - stroke: ${neutralForegroundHint}; - } - - :host(.paused) .determinate { - stroke: ${neutralForegroundHint}; - } - - @keyframes spin-infinite { - 0% { - stroke-dasharray: 0.01px 43.97px; - transform: rotate(0deg); - } - 50% { - stroke-dasharray: 21.99px 21.99px; - transform: rotate(450deg); - } - 100% { - stroke-dasharray: 0.01px 43.97px; - transform: rotate(1080deg); - } - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - .background { - stroke: ${SystemColors.Field}; - } - .determinate, - .indeterminate-indicator-1 { - stroke: ${SystemColors.ButtonText}; - } - :host(.paused) .determinate, - :host(.paused) .indeterminate-indicator-1 { - stroke: ${SystemColors.GrayText}; - } - `, - ), - ); diff --git a/packages/web-components/src/progress/progress-ring/progress-ring.vscode.definition.json b/packages/web-components/src/progress/progress-ring/progress-ring.vscode.definition.json deleted file mode 100644 index 5b1ec18a43637..0000000000000 --- a/packages/web-components/src/progress/progress-ring/progress-ring.vscode.definition.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-progress-ring", - "title": "Progress ring", - "description": "The Fluent UI progress-ring element", - "attributes": [ - { - "name": "value", - "title": "Value", - "description": "Value between 1 and 100 to represent the progress visually and to assistive technologies", - "default": "", - "required": false, - "type": "number" - }, - { - "name": "min", - "title": "Minimum", - "description": "The minimum value", - "default": 0, - "required": false, - "type": "number" - }, - { - "name": "max", - "title": "Maximum", - "description": "The maximum value", - "default": 100, - "required": false, - "type": "number" - }, - { - "name": "paused", - "title": "Paused", - "description": "Sets the paused state of the progress component", - "default": false, - "required": false, - "type": "boolean" - } - ], - "slots": [ - { - "name": "determinate", - "title": "Determinate slot", - "description": "Slot to provide custom visual representations of the determinate progress ring" - }, - { - "name": "indeterminate", - "title": "Indeterminate slot", - "description": "Slot to provide custom visual representations of the indeterminate progress ring" - } - ] - } - ] -} diff --git a/packages/web-components/src/progress/progress/fixtures/linear.html b/packages/web-components/src/progress/progress/fixtures/linear.html deleted file mode 100644 index b5252c4166028..0000000000000 --- a/packages/web-components/src/progress/progress/fixtures/linear.html +++ /dev/null @@ -1,24 +0,0 @@ -

Progress

-

Default

-
- - -
-

Paused

-
- - -
-

Custom Sizes

-
- - - - - - - - - - -
diff --git a/packages/web-components/src/progress/progress/index.ts b/packages/web-components/src/progress/progress/index.ts deleted file mode 100644 index 9694fb4402081..0000000000000 --- a/packages/web-components/src/progress/progress/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { BaseProgress, ProgressOptions, progressTemplate as template } from '@microsoft/fast-foundation'; -import { progressStyles as styles } from './progress.styles'; - -/** - * Progress base class - * @public - */ -export class Progress extends BaseProgress {} - -/** - * The Fluent Progress Element. Implements {@link @microsoft/fast-foundation#BaseProgress}, - * {@link @microsoft/fast-foundation#progressTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentProgress = Progress.compose({ - baseName: 'progress', - template, - styles, - indeterminateIndicator1: ` - - `, - indeterminateIndicator2: ` - - `, -}); - -/** - * Styles for Progress - * @public - */ -export const progressStyles = styles; diff --git a/packages/web-components/src/progress/progress/progress.stories.ts b/packages/web-components/src/progress/progress/progress.stories.ts deleted file mode 100644 index d33dff95734af..0000000000000 --- a/packages/web-components/src/progress/progress/progress.stories.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { fluentProgress } from './index'; - -export default { - title: 'Components/Progress', - component: fluentProgress, - argTypes: { - paused: { - control: { type: 'boolean' }, - }, - }, -}; - -const ProgressTemplate = ({ paused, value }) => ` - -`; - -export const Progress = ProgressTemplate.bind({}); - -Progress.args = { - paused: false, - value: 50, -}; - -const defaultExample = ` - -`; - -Progress.parameters = { - docs: { - source: { - code: defaultExample, - }, - }, -}; - -export const ProgressAnimated = ProgressTemplate.bind({}); - -ProgressAnimated.args = { - paused: false, -}; - -export const ProgressPaused = ProgressTemplate.bind({}); - -ProgressPaused.args = { - paused: true, -}; - -const animatedExample = ` - -`; - -const pausedExample = ` - -`; - -ProgressAnimated.parameters = { - docs: { - source: { - code: animatedExample, - }, - }, -}; - -ProgressPaused.parameters = { - docs: { - source: { - code: pausedExample, - }, - }, -}; diff --git a/packages/web-components/src/progress/progress/progress.styles.ts b/packages/web-components/src/progress/progress/progress.styles.ts deleted file mode 100644 index 249df334ee10a..0000000000000 --- a/packages/web-components/src/progress/progress/progress.styles.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { - display, - ElementDefinitionContext, - forcedColorsStylesheetBehavior, - ProgressOptions, -} from '@microsoft/fast-foundation'; -import { - accentFillRest, - designUnit, - neutralForegroundHint, - neutralStrokeStrongRest, - strokeWidth, -} from '../../design-tokens'; - -export const progressStyles: (context: ElementDefinitionContext, definition: ProgressOptions) => ElementStyles = ( - context: ElementDefinitionContext, - definition: ProgressOptions, -) => - css` - ${display('flex')} :host { - align-items: center; - height: calc((${strokeWidth} * 3) * 1px); - } - - .progress { - background-color: ${neutralStrokeStrongRest}; - border-radius: calc(${designUnit} * 1px); - width: 100%; - height: calc(${strokeWidth} * 1px); - display: flex; - align-items: center; - position: relative; - } - - .determinate { - background-color: ${accentFillRest}; - border-radius: calc(${designUnit} * 1px); - height: calc((${strokeWidth} * 3) * 1px); - transition: all 0.2s ease-in-out; - display: flex; - } - - .indeterminate { - height: calc((${strokeWidth} * 3) * 1px); - border-radius: calc(${designUnit} * 1px); - display: flex; - width: 100%; - position: relative; - overflow: hidden; - } - - .indeterminate-indicator-1 { - position: absolute; - opacity: 0; - height: 100%; - background-color: ${accentFillRest}; - border-radius: calc(${designUnit} * 1px); - animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); - width: 40%; - animation: indeterminate-1 2s infinite; - } - - .indeterminate-indicator-2 { - position: absolute; - opacity: 0; - height: 100%; - background-color: ${accentFillRest}; - border-radius: calc(${designUnit} * 1px); - animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); - width: 60%; - animation: indeterminate-2 2s infinite; - } - - :host(.paused) .indeterminate-indicator-1, - :host(.paused) .indeterminate-indicator-2 { - animation: none; - background-color: ${neutralForegroundHint}; - width: 100%; - opacity: 1; - } - - :host(.paused) .determinate { - background-color: ${neutralForegroundHint}; - } - - @keyframes indeterminate-1 { - 0% { - opacity: 1; - transform: translateX(-100%); - } - 70% { - opacity: 1; - transform: translateX(300%); - } - 70.01% { - opacity: 0; - } - 100% { - opacity: 0; - transform: translateX(300%); - } - } - - @keyframes indeterminate-2 { - 0% { - opacity: 0; - transform: translateX(-150%); - } - 29.99% { - opacity: 0; - } - 30% { - opacity: 1; - transform: translateX(-150%); - } - 100% { - transform: translateX(166.66%); - opacity: 1; - } - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - .indeterminate-indicator-1, - .indeterminate-indicator-2, - .determinate, - .progress { - background-color: ${SystemColors.ButtonText}; - } - :host(.paused) .indeterminate-indicator-1, - :host(.paused) .indeterminate-indicator-2, - :host(.paused) .determinate { - background-color: ${SystemColors.GrayText}; - } - `, - ), - ); diff --git a/packages/web-components/src/progress/progress/progress.vscode.definition.json b/packages/web-components/src/progress/progress/progress.vscode.definition.json deleted file mode 100644 index 66f575a36d0f0..0000000000000 --- a/packages/web-components/src/progress/progress/progress.vscode.definition.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-progress", - "title": "Progress", - "description": "The Fluent UI progress element", - "attributes": [ - { - "name": "value", - "title": "Value", - "description": "Value between 1 and 100 to represent the progress visually and to assistive technologies", - "default": "", - "required": false, - "type": "number" - }, - { - "name": "min", - "title": "Minimum", - "description": "The minimum value", - "default": 0, - "required": false, - "type": "number" - }, - { - "name": "max", - "title": "Maximum", - "description": "The maximum value", - "default": 100, - "required": false, - "type": "number" - }, - { - "name": "paused", - "title": "Paused", - "description": "Sets the paused state of the progress component", - "default": false, - "required": false, - "type": "boolean" - } - ], - "slots": [ - { - "name": "determinate", - "title": "Determinate slot", - "description": "Slot to provide custom visual representations of the determinate progress bar" - }, - { - "name": "indeterminate", - "title": "Indeterminate slot", - "description": "Slot to provide custom visual representations of the indeterminate progress bar" - } - ] - } - ] -} diff --git a/packages/web-components/src/radio-group/fixtures/radio-group.html b/packages/web-components/src/radio-group/fixtures/radio-group.html deleted file mode 100644 index 169f592807e60..0000000000000 --- a/packages/web-components/src/radio-group/fixtures/radio-group.html +++ /dev/null @@ -1,76 +0,0 @@ -

Radio Group

- -

Defaults

-
- - - One - Two - -
- -

Single radio

-
- - - Michael Jordan - -
- -

With label outside group

-
- - - Apples - Oranges - Bananas - Kiwi - Grapefruit - Mango - Blueberries - Strawberries - Pineapple - -
- -

Within toolbar

-
-
- - - back - forward - refresh - - -
-
- -

Disabled

-
- - - Lamborghini - Ferari - -
- -

Readonly

-
- - - Word - Excel - -
- -

Preset value

-
- - - Ice Man - Maverick - Viper - Jester - -
diff --git a/packages/web-components/src/radio-group/index.ts b/packages/web-components/src/radio-group/index.ts deleted file mode 100644 index 9e1fc00bdeedd..0000000000000 --- a/packages/web-components/src/radio-group/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RadioGroup, radioGroupTemplate as template } from '@microsoft/fast-foundation'; -import { radioGroupStyles as styles } from './radio-group.styles'; - -/** - * The Fluent Radio Group Element. Implements {@link @microsoft/fast-foundation#RadioGroup}, - * {@link @microsoft/fast-foundation#radioGroupTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentRadioGroup = RadioGroup.compose({ - baseName: 'radio-group', - template, - styles, -}); - -/** - * Styles for RadioGroup - * @public - */ -export const radioGroupStyles = styles; - -/** - * Radio group base class - * @public - */ -export { RadioGroup }; diff --git a/packages/web-components/src/radio-group/radio-group.stories.ts b/packages/web-components/src/radio-group/radio-group.stories.ts deleted file mode 100644 index 3fbf7c7685d30..0000000000000 --- a/packages/web-components/src/radio-group/radio-group.stories.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { fluentRadioGroup } from './index'; - -export default { - title: 'Components/Radio Group', - component: fluentRadioGroup, - argTypes: { - disabled: { - control: { type: 'boolean' }, - }, - required: { - control: { type: 'boolean' }, - }, - }, -}; - -const RadioGroupTemplate = ({ disabled, required }) => ` - - Apples - Bananas - Tomatoes - `; - -export const RadioGroup = RadioGroupTemplate.bind({}); - -RadioGroup.args = { - disabled: false, - required: false, -}; - -const example = ` - - - Apples - Bananas - Bananas - -`; - -RadioGroup.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/radio-group/radio-group.styles.ts b/packages/web-components/src/radio-group/radio-group.styles.ts deleted file mode 100644 index 7986fa0aac56d..0000000000000 --- a/packages/web-components/src/radio-group/radio-group.styles.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { display, ElementDefinitionContext, FoundationElementDefinition } from '@microsoft/fast-foundation'; - -export const radioGroupStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => css` - ${display('flex')} :host { - align-items: flex-start; - flex-direction: column; - } - - .positioning-region { - display: flex; - flex-wrap: wrap; - } - - :host([orientation='vertical']) .positioning-region { - flex-direction: column; - } - - :host([orientation='horizontal']) .positioning-region { - flex-direction: row; - } -`; diff --git a/packages/web-components/src/radio-group/radio-group.vscode.definition.json b/packages/web-components/src/radio-group/radio-group.vscode.definition.json deleted file mode 100644 index 82b25f15aab91..0000000000000 --- a/packages/web-components/src/radio-group/radio-group.vscode.definition.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-radio-group", - "title": "Radio group", - "description": "The Fluent UI radio-group element", - "attributes": [ - { - "name": "value", - "title": "Value", - "description": "The value of the radio group", - "required": false, - "type": "string" - }, - { - "name": "orientation", - "title": "Orientation", - "description": "The visual orientation of the group", - "default": "horizontal", - "values": [{ "name": "horizontal" }, { "name": "vertical" }], - "required": false, - "type": "string" - }, - { - "name": "name", - "title": "Name", - "description": "Setting this value will set the name value for all child radios", - "type": "string", - "default": "", - "required": false - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Disables the radio group and child radios", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "readonly", - "title": "Readonly", - "description": "When true, the child radios will be immutable by user interaction", - "type": "boolean", - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "Supports fluent-radio elements or elements with a role of 'radio'" - }, - { - "name": "label", - "title": "Label slot", - "description": "The visual label for the group" - } - ] - } - ] -} diff --git a/packages/web-components/src/radio/fixtures/radio.html b/packages/web-components/src/radio/fixtures/radio.html deleted file mode 100644 index a97ba92cd5e2c..0000000000000 --- a/packages/web-components/src/radio/fixtures/radio.html +++ /dev/null @@ -1,30 +0,0 @@ -

Radio

- -

Defaults

- -
- label -
- -

Checked

- - - -

Required

- - - -

Disabled

- -label -checked - -

Visual vs audio label

- - Visible label - - -
- - -
diff --git a/packages/web-components/src/radio/index.ts b/packages/web-components/src/radio/index.ts deleted file mode 100644 index 1a24489947f51..0000000000000 --- a/packages/web-components/src/radio/index.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Radio, RadioOptions, radioTemplate as template } from '@microsoft/fast-foundation'; -import { radioStyles as styles } from './radio.styles'; - -/** - * The Fluent Radio Element. Implements {@link @microsoft/fast-foundation#Radio}, - * {@link @microsoft/fast-foundation#radioTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentRadio = Radio.compose({ - baseName: 'radio', - template, - styles, - checkedIndicator: ` - - - - `, -}); - -/** - * Styles for Radio - * @public - */ -export const RadioStyles = styles; - -/** - * Radio base class - * @public - */ -export { Radio }; diff --git a/packages/web-components/src/radio/radio.stories.ts b/packages/web-components/src/radio/radio.stories.ts deleted file mode 100644 index fddf874476334..0000000000000 --- a/packages/web-components/src/radio/radio.stories.ts +++ /dev/null @@ -1,47 +0,0 @@ -// import Examples from './fixtures/radio.html'; -import { fluentRadio } from './index'; - -export default { - title: 'Components/Radio', - component: fluentRadio, - argTypes: { - checked: { - control: { type: 'boolean' }, - }, - disabled: { - control: { type: 'boolean' }, - }, - required: { - control: { type: 'boolean' }, - }, - }, -}; - -const RadioTemplate = ({ checked, disabled, required, label }) => ` - ${label} -`; - -export const Radio = RadioTemplate.bind({}); - -Radio.args = { - label: 'Label', - checked: false, - disabled: false, - required: false, -}; - -const example = ` - -`; - -Radio.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/radio/radio.styles.ts b/packages/web-components/src/radio/radio.styles.ts deleted file mode 100644 index 641ea2eb3ca37..0000000000000 --- a/packages/web-components/src/radio/radio.styles.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { - disabledCursor, - display, - ElementDefinitionContext, - focusVisible, - forcedColorsStylesheetBehavior, - RadioOptions, -} from '@microsoft/fast-foundation'; -import { heightNumber } from '../styles'; -import { - accentFillActive, - accentFillHover, - accentFillRest, - designUnit, - disabledOpacity, - foregroundOnAccentRest, - neutralFillInputAltActive, - neutralFillInputAltFocus, - neutralFillInputAltHover, - neutralFillInputAltRest, - neutralForegroundRest, - neutralStrokeStrongActive, - neutralStrokeStrongHover, - neutralStrokeStrongRest, - strokeWidth, -} from '../design-tokens'; -import { typeRampBase } from '../styles/patterns/type-ramp'; -import { focusTreatmentTight } from '../styles/focus'; - -export const radioStyles: (context: ElementDefinitionContext, definition: RadioOptions) => ElementStyles = ( - context: ElementDefinitionContext, - definition: RadioOptions, -) => - css` - ${display('inline-flex')} :host { - --input-size: calc((${heightNumber} / 2) + ${designUnit}); - align-items: center; - outline: none; - ${ - /* - * Chromium likes to select label text or the default slot when - * the radio button is clicked. Maybe there is a better solution here? - */ '' - } user-select: none; - position: relative; - flex-direction: row; - transition: all 0.2s ease-in-out; - } - - .control { - position: relative; - width: calc(var(--input-size) * 1px); - height: calc(var(--input-size) * 1px); - box-sizing: border-box; - border-radius: 50%; - border: calc(${strokeWidth} * 1px) solid ${neutralStrokeStrongRest}; - background: ${neutralFillInputAltRest}; - cursor: pointer; - } - - .label__hidden { - display: none; - visibility: hidden; - } - - .label { - ${typeRampBase} - color: ${neutralForegroundRest}; - ${ - /* Need to discuss with Brian how HorizontalSpacingNumber can work. https://github.com/microsoft/fast/issues/2766 */ '' - } padding-inline-start: calc(${designUnit} * 2px + 2px); - margin-inline-end: calc(${designUnit} * 2px + 2px); - cursor: pointer; - } - - .control, - slot[name='checked-indicator'] { - flex-shrink: 0; - } - - slot[name='checked-indicator'] { - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; - fill: ${foregroundOnAccentRest}; - opacity: 0; - pointer-events: none; - } - - :host(:not(.disabled):hover) .control { - background: ${neutralFillInputAltHover}; - border-color: ${neutralStrokeStrongHover}; - } - - :host(:not(.disabled):active) .control { - background: ${neutralFillInputAltActive}; - border-color: ${neutralStrokeStrongActive}; - } - - :host(:not(.disabled):active) slot[name='checked-indicator'] { - opacity: 1; - } - - :host(:${focusVisible}) .control { - ${focusTreatmentTight} - background: ${neutralFillInputAltFocus}; - } - - :host(.checked) .control { - background: ${accentFillRest}; - border-color: transparent; - } - - :host(.checked:not(.disabled):hover) .control { - background: ${accentFillHover}; - border-color: transparent; - } - - :host(.checked:not(.disabled):active) .control { - background: ${accentFillActive}; - border-color: transparent; - } - - :host(.disabled) .label, - :host(.readonly) .label, - :host(.readonly) .control, - :host(.disabled) .control { - cursor: ${disabledCursor}; - } - - :host(.checked) slot[name='checked-indicator'] { - opacity: 1; - } - - :host(.disabled) { - opacity: ${disabledOpacity}; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - .control { - background: ${SystemColors.Field}; - border-color: ${SystemColors.FieldText}; - } - :host(:not(.disabled):hover) .control, - :host(:not(.disabled):active) .control { - border-color: ${SystemColors.Highlight}; - } - :host(:${focusVisible}) .control { - forced-color-adjust: none; - background: ${SystemColors.Field}; - outline-color: ${SystemColors.FieldText}; - } - :host(.checked:not(.disabled):hover) .control, - :host(.checked:not(.disabled):active) .control { - border-color: ${SystemColors.Highlight}; - background: ${SystemColors.Highlight}; - } - :host(.checked) slot[name='checked-indicator'] { - fill: ${SystemColors.Highlight}; - } - :host(.checked:hover) .control slot[name='checked-indicator'] { - fill: ${SystemColors.HighlightText}; - } - :host(.disabled) { - opacity: 1; - } - :host(.disabled) .label { - color: ${SystemColors.GrayText}; - } - :host(.disabled) .control, - :host(.checked.disabled) .control { - background: ${SystemColors.Field}; - border-color: ${SystemColors.GrayText}; - } - :host(.disabled) slot[name='checked-indicator'], - :host(.checked.disabled) slot[name='checked-indicator'] { - fill: ${SystemColors.GrayText}; - } - `, - ), - ); diff --git a/packages/web-components/src/radio/radio.vscode.definition.json b/packages/web-components/src/radio/radio.vscode.definition.json deleted file mode 100644 index bc58c2952552e..0000000000000 --- a/packages/web-components/src/radio/radio.vscode.definition.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-radio", - "title": "Radio", - "description": "The Fluent UI radio element", - "attributes": [ - { - "name": "checked", - "title": "Checked", - "description": "Whether or not this radio is checked by default", - "required": false, - "type": "boolean" - }, - { - "name": "name", - "title": "Name", - "description": "This element's value will be surfaced during form submission under the provided name", - "type": "string", - "default": "", - "required": false - }, - { - "name": "required", - "title": "Required", - "description": "Require the field to be completed prior to form submission", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Sets the disabled state of the radio", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "readonly", - "title": "Readonly", - "description": "When true, the control will be immutable by user interaction", - "type": "boolean", - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the radio represents its visual label" - }, - { - "name": "checked-indicator", - "title": "Checked indicator slot", - "description": "Slot to provide a custom icon to represent the checked state" - } - ] - } - ] -} diff --git a/packages/web-components/src/search/fixtures/search.html b/packages/web-components/src/search/fixtures/search.html deleted file mode 100644 index 943d34f3f2560..0000000000000 --- a/packages/web-components/src/search/fixtures/search.html +++ /dev/null @@ -1,109 +0,0 @@ -

Search

-

Default

- -Label - -

Full Width

- - -

Placeholder

- - - -

Required

- - - -

Disabled

- -label - - - - - - - - -

Read only

- -label - - -

Autofocus

-autofocus - - -

With start

- - - - - - - -

With end

- - - - - - -

Filled

-
Default
- -label - -
Placeholder
- - - -
Required
- - - -
Disabled
- -label - - - - - - - - -
Read only
- -label - - -

Visual vs audio label

- - Visible label - - - -

Audio label only

- - - - - -

With aria-label

- - -
- -

In a form

- - -
diff --git a/packages/web-components/src/search/index.ts b/packages/web-components/src/search/index.ts deleted file mode 100644 index 8eff8a70f889a..0000000000000 --- a/packages/web-components/src/search/index.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { attr } from '@microsoft/fast-element'; -import { Search as FoundationSearch, SearchOptions } from '@microsoft/fast-foundation'; -import { searchTemplate as template } from './search.template'; -import { searchStyles as styles } from './search.styles'; - -/** - * Search appearances - * @public - */ -export type SearchAppearance = 'filled' | 'outline'; - -/** - * The Fluent search class - * @internal - */ -export class Search extends FoundationSearch { - /** - * The appearance of the element. - * - * @public - * @remarks - * HTML Attribute: appearance - */ - @attr - public appearance: SearchAppearance = 'outline'; -} - -/** - * The Fluent Search Custom Element. Implements {@link @microsoft/fast-foundation#Search}, - * {@link @microsoft/fast-foundation#searchTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - * - * {@link https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus | delegatesFocus} - */ -export const fluentSearch = Search.compose({ - baseName: 'search', - baseClass: FoundationSearch, - template, - styles, - start: ``, - shadowOptions: { - delegatesFocus: true, - }, -}); - -export * from './search.template'; - -/** - * Styles for Search - * @public - */ -export const searchStyles = styles; diff --git a/packages/web-components/src/search/search.stories.ts b/packages/web-components/src/search/search.stories.ts deleted file mode 100644 index a00d6a7b577bb..0000000000000 --- a/packages/web-components/src/search/search.stories.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { fluentSearch } from './index'; - -export default { - title: 'Components/Search', - component: fluentSearch, - argTypes: { - appearance: { - options: ['filled', 'outline'], - defaultValue: 'outline', - control: { type: 'radio' }, - }, - autoFocus: { - description: 'Automatically focuses the control', - control: { type: 'boolean' }, - }, - disabled: { - description: 'The search box should be submitted with the form but should not be editable', - control: { type: 'boolean' }, - }, - list: { - control: { type: 'text' }, - }, - maxlength: { - control: { type: 'number' }, - }, - name: { - control: { type: 'text' }, - }, - minlength: { - control: { type: 'number' }, - }, - pattern: { - description: `A regular expression the input's contents must match in order to be valid`, - control: { type: 'text' }, - }, - placeholder: { - description: 'An exemplar value to display in the input field whenever it is empty', - defaultValue: 'Placeholder', - control: { type: 'text' }, - }, - readonly: { - control: { type: 'boolean' }, - }, - required: { - control: { type: 'boolean' }, - }, - spellcheck: { - control: { type: 'boolean' }, - }, - }, -}; - -const SearchTemplate = ({ - appearance, - autoFocus, - disabled, - list, - maxlength, - name, - minlength, - pattern, - placeholder, - readonly, - required, - size, - spellcheck, -}) => - ``; - -export const Search = SearchTemplate.bind({}); - -Search.args = { - placeholder: 'placeholder', - autoFocus: false, - disabled: false, - readonly: false, - required: false, -}; - -const example = ` - -`; - -Search.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/search/search.styles.ts b/packages/web-components/src/search/search.styles.ts deleted file mode 100644 index cc20bdd6e5967..0000000000000 --- a/packages/web-components/src/search/search.styles.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - Button, - DesignToken, - display, - ElementDefinitionContext, - forcedColorsStylesheetBehavior, - SearchOptions, -} from '@microsoft/fast-foundation'; -import { - baseInputStyles, - heightNumber, - inputFilledStyles, - inputForcedColorStyles, - inputOutlineStyles, - inputStateStyles, -} from '../styles'; -import { appearanceBehavior } from '../utilities/behaviors'; -import { controlCornerRadius, density, designUnit, neutralFillInputRecipe, neutralFillStealthRecipe, neutralForegroundRest } from '../design-tokens'; -import { typeRampBase } from '../styles/patterns/type-ramp'; -import { Swatch } from '../color/swatch'; - -const logicalControlSelector: string = '.root'; - -const clearButtonHover = DesignToken.create("clear-button-hover").withDefault( - (target: HTMLElement) => { - const buttonRecipe = neutralFillStealthRecipe.getValueFor(target); - const inputRecipe = neutralFillInputRecipe.getValueFor(target); - return buttonRecipe.evaluate(target, inputRecipe.evaluate(target).focus).hover; - } -); - -const clearButtonActive = DesignToken.create("clear-button-active").withDefault( - (target: HTMLElement) => { - const buttonRecipe = neutralFillStealthRecipe.getValueFor(target); - const inputRecipe = neutralFillInputRecipe.getValueFor(target); - return buttonRecipe.evaluate(target, inputRecipe.evaluate(target).focus).active; - } -); - -export const searchStyles: (context: ElementDefinitionContext, definition: SearchOptions) => ElementStyles = ( - context: ElementDefinitionContext, - definition: SearchOptions, -) => - css` - ${display('inline-block')} - - ${baseInputStyles(context, definition, logicalControlSelector)} - - ${inputStateStyles(context, definition, logicalControlSelector)} - - .root { - display: flex; - flex-direction: row; - } - .control { - -webkit-appearance: none; - color: inherit; - background: transparent; - border: 0; - height: calc(100% - 4px); - margin-top: auto; - margin-bottom: auto; - padding: 0 calc(${designUnit} * 2px + 1px); - font-family: inherit; - font-size: inherit; - line-height: inherit; - } - .clear-button { - display: inline-flex; - align-items: center; - margin: 1px; - height: calc(100% - 2px); - opacity: 0; - background: transparent; - color: ${neutralForegroundRest}; - fill: currentcolor; - border: none; - border-radius: calc(${controlCornerRadius} * 1px); - min-width: calc(${heightNumber} * 1px); - ${typeRampBase} - outline: none; - padding: 0 calc((10 + (${designUnit} * 2 * ${density})) * 1px); - } - .clear-button:hover { - background: ${clearButtonHover}; - } - .clear-button:active { - background: ${clearButtonActive}; - } - :host(:hover:not([disabled], [readOnly])) .clear-button, - :host(:active:not([disabled], [readOnly])) .clear-button, - :host(:focus-within:not([disabled], [readOnly])) .clear-button { - opacity: 1; - } - :host(:hover:not([disabled], [readOnly])) .clear-button__hidden, - :host(:active:not([disabled], [readOnly])) .clear-button__hidden, - :host(:focus-within:not([disabled], [readOnly])) .clear-button__hidden { - opacity: 0; - } - .control::-webkit-search-cancel-button { - -webkit-appearance: none; - } - .input-wrapper { - display: flex; - position: relative; - width: 100%; - } - .start, - .end { - display: flex; - margin: 1px; - align-items: center; - } - .start { - display: flex; - margin-inline-start: 11px; - } - ::slotted([slot="end"]) { - height: 100% - } - .clear-button__hidden { - opacity: 0; - } - .end { - margin-inline-end: 11px; - } - ::slotted(${context.tagFor(Button)}) { - margin-inline-end: 1px; - } - `.withBehaviors( - appearanceBehavior('outline', inputOutlineStyles(context, definition, logicalControlSelector)), - appearanceBehavior('filled', inputFilledStyles(context, definition, logicalControlSelector)), - forcedColorsStylesheetBehavior(inputForcedColorStyles(context, definition, logicalControlSelector)), - ); diff --git a/packages/web-components/src/search/search.template.ts b/packages/web-components/src/search/search.template.ts deleted file mode 100644 index 8d220d35fc51d..0000000000000 --- a/packages/web-components/src/search/search.template.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { html, ref, slotted } from '@microsoft/fast-element'; -import type { ViewTemplate } from '@microsoft/fast-element'; -import { - ElementDefinitionContext, - endSlotTemplate, - Search, - SearchOptions, - startSlotTemplate, - whitespaceFilter, -} from '@microsoft/fast-foundation'; - -/** - * @public - */ -export const searchTemplate: (context: ElementDefinitionContext, definition: SearchOptions) => ViewTemplate = ( - context: ElementDefinitionContext, - definition: SearchOptions, -) => html` - -`; diff --git a/packages/web-components/src/search/search.vscode.definition.json b/packages/web-components/src/search/search.vscode.definition.json deleted file mode 100644 index 19c2ab1908ea8..0000000000000 --- a/packages/web-components/src/search/search.vscode.definition.json +++ /dev/null @@ -1,145 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-search", - "title": "Search", - "description": "The Fluent UI search element", - "attributes": [ - { - "name": "value", - "title": "Value", - "description": "The HTML value attribute of the search", - "required": false, - "type": "string" - }, - { - "name": "appearance", - "title": "Appearance", - "description": "The field's visual treatment", - "default": "outline", - "values": [{ "name": "outline" }, { "name": "filled" }], - "type": "string", - "required": false - }, - { - "name": "autofocus", - "title": "Autofocus", - "description": "Determines if the element should receive document focus on page load", - "required": false, - "type": "boolean", - "default": false - }, - { - "name": "placeholder", - "title": "Placeholder", - "description": "Sets the placeholder value of the element, generally used to provide a hint to the user", - "required": false, - "type": "string" - }, - { - "name": "list", - "title": "List ID", - "description": "Allows associating a datalist to the component", - "required": false, - "type": "string", - "default": "" - }, - { - "name": "maxlength", - "title": "Maximum length", - "description": "The maximum number of characters a user can enter", - "required": false, - "type": "number" - }, - { - "name": "minlength", - "title": "Minimum length", - "description": "The minimum number of characters a user can enter", - "required": false, - "type": "number" - }, - { - "name": "pattern", - "title": "Validation pattern", - "description": "A regular expression that the value must match to pass validation", - "required": false, - "type": "string" - }, - { - "name": "size", - "title": "Size", - "description": "Sets the width of the element to a specified number of characters", - "required": false, - "type": "number" - }, - { - "name": "spellcheck", - "title": "Spellcheck", - "description": "Controls whether or not to enable spell checking for the input field, or if the default spell checking configuration should be used", - "required": false, - "type": "boolean" - }, - { - "name": "name", - "title": "Name", - "description": "This element's value will be surfaced during form submission under the provided name", - "type": "string", - "default": "", - "required": false - }, - { - "name": "required", - "title": "Required", - "description": "Require the field to be completed prior to form submission", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Sets the disabled state of the field", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "readonly", - "title": "Readonly", - "description": "When true, the control will be immutable by user interaction", - "type": "boolean", - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the field represents its visual label" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned before the input area" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the input area" - }, - { - "name": "clear-button", - "title": "Clear button slot", - "description": "Contents of the clear button slot are positioned after the content and is what clears the value when a value is set" - }, - { - "name": "clear-glyph", - "title": "Clear glyph slot", - "description": "Contents of the clear button" - } - ] - } - ] -} diff --git a/packages/web-components/src/select/fixtures/base.html b/packages/web-components/src/select/fixtures/base.html deleted file mode 100644 index f14d659479612..0000000000000 --- a/packages/web-components/src/select/fixtures/base.html +++ /dev/null @@ -1,165 +0,0 @@ -

Select

- -

Default

- - This option has no value - This option is disabled - This option has a value - This option is selected by default - - -

Filled

- - This option has no value - This option is disabled - This option has a value - This option is selected by default - - -

Stealth

- - This option has no value - This option is disabled - This option has a value - This option is selected by default - - -

With Label

- - - Small - Medium - Large - Extra Large - - -

Disabled

- - This option is not selectable - - - - This option is disabled - This option is not disabled - This option is not disabled - - -

Selected Option

- - Option One - Option Two - Option Three - Option Four - - -

Custom Indicator and Icons

- - - - - - - - - - - - - - - - - - Option One - - - - - - - - - Option Two - - Option Three - Option Four - - -

Long list

- - Alabama - Alaska - Arizona - Arkansas - California - Colorado - Connecticut - Delaware - Florida - Georgia - Hawaii - Idaho - Illinois - Indiana - Iowa - Kansas - Kentucky - Louisiana - Maine - Maryland - Massachusets - Michigan - Minnesota - Mississippi - Missouri - Montana - Nebraska - Nevada - New Hampshire - New Jersey - New Mexico - New York - North Carolina - North Dakota - Ohio - Oklahoma - Oregon - Pennsylvania - Rhode Island - South Carolina - South Dakota - Texas - Tennessee - Utah - Vermont - Virginia - Washington - Wisconsin - West Virginia - Wyoming - - -

Forced positions

- - Position forced above - Option Two - - - - Position forced below - Option Two - diff --git a/packages/web-components/src/select/index.ts b/packages/web-components/src/select/index.ts deleted file mode 100644 index acef807e26cf5..0000000000000 --- a/packages/web-components/src/select/index.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { attr } from '@microsoft/fast-element'; -import { Select as FoundationSelect, SelectOptions, selectTemplate as template } from '@microsoft/fast-foundation'; -import { fillColor, neutralLayerFloating } from '../design-tokens'; -import { selectStyles as styles } from './select.styles'; - -/** - * Select appearances - * @public - */ -export type SelectAppearance = 'filled' | 'outline' | 'stealth'; - -/** - * The Fluent select class - * @internal - */ -export class Select extends FoundationSelect { - /** - * The appearance of the element. - * - * @public - * @remarks - * HTML Attribute: appearance - */ - @attr({ mode: 'fromView' }) - public appearance: SelectAppearance; - - /** - * @internal - */ - public appearanceChanged(oldValue: SelectAppearance, newValue: SelectAppearance): void { - if (oldValue !== newValue) { - this.classList.add(newValue); - this.classList.remove(oldValue); - } - } - - /** - * @internal - */ - public connectedCallback(): void { - super.connectedCallback(); - - if (!this.appearance) { - this.appearance = 'outline'; - } - - if (this.listbox) { - fillColor.setValueFor(this.listbox, neutralLayerFloating); - } - } -} - -/** - * The Fluent select Custom Element. Implements, {@link @microsoft/fast-foundation#Select} - * {@link @microsoft/fast-foundation#selectTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - * - */ -export const fluentSelect = Select.compose({ - baseName: 'select', - baseClass: FoundationSelect, - template, - styles, - indicator: ` - - - - `, -}); - -/** - * Styles for Select - * @public - */ -export const selectStyles = styles; diff --git a/packages/web-components/src/select/select.stories.ts b/packages/web-components/src/select/select.stories.ts deleted file mode 100644 index 2f4f670dffd0c..0000000000000 --- a/packages/web-components/src/select/select.stories.ts +++ /dev/null @@ -1,58 +0,0 @@ -import '../listbox-option'; -import { fluentSelect } from './index'; - -export default { - title: 'Components/Select', - component: fluentSelect, - argTypes: { - appearance: { - options: ['filled', 'outline', 'stealth'], - control: { type: 'radio' }, - defaultValue: 'outline', - }, - disabled: { - control: { type: 'boolean' }, - }, - position: { - options: ['above', 'below'], - control: { type: 'radio' }, - defaultValue: 'below', - }, - }, -}; - -const SelectTemplate = ({ appearance, disabled, position }) => ` - - Option One - Option Two - Option Three - Option Four - -`; - -export const Select = SelectTemplate.bind({}); -Select.args = { - disabled: false, -}; - -const example = ` - - This option has no value - This option is disabled - This option has a value - This option is selected by default - -`; - -Select.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/select/select.styles.ts b/packages/web-components/src/select/select.styles.ts deleted file mode 100644 index 4a0dd537f65c0..0000000000000 --- a/packages/web-components/src/select/select.styles.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - disabledCursor, - display, - ElementDefinitionContext, - focusVisible, - forcedColorsStylesheetBehavior, - SelectOptions, -} from '@microsoft/fast-foundation'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { elevationShadowFlyout } from '../styles/elevation'; -import { heightNumber } from '../styles/size'; -import { appearanceBehavior } from '../utilities/behaviors'; -import { - bodyFont, - controlCornerRadius, - designUnit, - disabledOpacity, - fillColor, - layerCornerRadius, - neutralForegroundRest, - strokeWidth, -} from '../design-tokens'; -import { typeRampBase } from '../styles/patterns/type-ramp'; -import { focusTreatmentBase } from '../styles/focus'; -import { inputFilledStyles, inputForcedColorStyles, NeutralButtonStyles, StealthButtonStyles } from '../styles'; - -const logicalControlSelector: string = '.control'; -const interactivitySelector: string = ':not([disabled]):not([open])'; -const nonInteractivitySelector: string = '[disabled]'; - -/** - * The base styles for a select and combobox, without `appearance` visual differences. - * - * @internal - */ -export const baseSelectStyles: (context: ElementDefinitionContext, definition: SelectOptions) => ElementStyles = ( - context: ElementDefinitionContext, - definition: SelectOptions, -) => - css` - ${display('inline-flex')} - - :host { - border-radius: calc(${controlCornerRadius} * 1px); - box-sizing: border-box; - color: ${neutralForegroundRest}; - fill: currentcolor; - font-family: ${bodyFont}; - position: relative; - user-select: none; - min-width: 250px; - vertical-align: top; - } - - .listbox { - box-shadow: ${elevationShadowFlyout}; - background: ${fillColor}; - border-radius: calc(${layerCornerRadius} * 1px); - box-sizing: border-box; - display: inline-flex; - flex-direction: column; - left: 0; - max-height: calc(var(--max-height) - (${heightNumber} * 1px)); - padding: calc((${designUnit} - ${strokeWidth} ) * 1px); - overflow-y: auto; - position: absolute; - width: 100%; - z-index: 1; - margin: 1px 0; - border: calc(${strokeWidth} * 1px) solid transparent; - } - - .listbox[hidden] { - display: none; - } - - .control { - border: calc(${strokeWidth} * 1px) solid transparent; - border-radius: calc(${controlCornerRadius} * 1px); - height: calc(${heightNumber} * 1px); - align-items: center; - box-sizing: border-box; - cursor: pointer; - display: flex; - ${typeRampBase} - min-height: 100%; - padding: 0 calc(${designUnit} * 2.25px); - width: 100%; - } - - :host(:${focusVisible}) { - ${focusTreatmentBase} - } - - :host([disabled]) .control { - cursor: ${disabledCursor}; - opacity: ${disabledOpacity}; - user-select: none; - } - - :host([open][position='above']) .listbox { - bottom: calc((${heightNumber} + ${designUnit} * 2) * 1px); - } - - :host([open][position='below']) .listbox { - top: calc((${heightNumber} + ${designUnit} * 2) * 1px); - } - - .selected-value { - font-family: inherit; - flex: 1 1 auto; - text-align: start; - } - - .indicator { - flex: 0 0 auto; - margin-inline-start: 1em; - } - - slot[name='listbox'] { - display: none; - width: 100%; - } - - :host([open]) slot[name='listbox'] { - display: flex; - position: absolute; - } - - .start { - margin-inline-end: 11px; - } - - .end { - margin-inline-start: 11px; - } - - .start, - .end, - .indicator, - ::slotted(svg) { - display: flex; - } - - ::slotted([role='option']) { - flex: 0 0 auto; - } - `; - -/** - * @internal - */ -export const baseSelectForcedColorStyles: ( - context: ElementDefinitionContext, - definition: SelectOptions -) => ElementStyles = ( - context: ElementDefinitionContext, - definition: SelectOptions, -) => - css` - :host([open]) .listbox { - background: ${SystemColors.ButtonFace}; - border-color: ${SystemColors.CanvasText}; - } - `; - -export const selectStyles: (context: ElementDefinitionContext, definition: SelectOptions) => ElementStyles = ( - context: ElementDefinitionContext, - definition: SelectOptions, -) => - baseSelectStyles(context, definition) - .withBehaviors( - appearanceBehavior('outline', NeutralButtonStyles(context, definition, interactivitySelector, nonInteractivitySelector)), - appearanceBehavior('filled', - inputFilledStyles(context, definition, logicalControlSelector, interactivitySelector) - .withBehaviors(forcedColorsStylesheetBehavior(inputForcedColorStyles(context, definition, logicalControlSelector, interactivitySelector))) - ), - appearanceBehavior('stealth', StealthButtonStyles(context, definition, interactivitySelector, nonInteractivitySelector)), - forcedColorsStylesheetBehavior(baseSelectForcedColorStyles(context, definition)) - ); diff --git a/packages/web-components/src/select/select.vscode.definition.json b/packages/web-components/src/select/select.vscode.definition.json deleted file mode 100644 index 59b061938cf2e..0000000000000 --- a/packages/web-components/src/select/select.vscode.definition.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-select", - "title": "Select", - "description": "The Fluent UI select element", - "attributes": [ - { - "name": "appearance", - "title": "Appearance", - "description": "The select's visual treatment", - "type": "string", - "values": [ - { - "name": "filled" - }, - { - "name": "outline" - }, - { - "name": "stealth" - } - ], - "default": "outline", - "required": false - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Sets the disabled state of the select", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "name", - "title": "Name", - "description": "This element's value will be surfaced during form submission under the provided name", - "type": "string", - "default": "", - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "Supports fluent-option or option elements" - }, - { - "name": "button-container", - "title": "Button container slot", - "description": "Slot to replace the entire invoking element and its contents" - }, - { - "name": "selected-value", - "title": "Selected value slot", - "description": "Slot to replace the displayed value contents" - }, - { - "name": "indicator", - "title": "Indicator slot", - "description": "Slot to provide a custom icon to represent the visual indicator" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned before the button container" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the button container and after the indicator" - } - ] - } - ] -} diff --git a/packages/web-components/src/skeleton/fixtures/base.html b/packages/web-components/src/skeleton/fixtures/base.html deleted file mode 100644 index 4bec31defa2eb..0000000000000 --- a/packages/web-components/src/skeleton/fixtures/base.html +++ /dev/null @@ -1,65 +0,0 @@ - - -

Skeleton

- -

Used as element blocks

- - - - - - - - -

Used as element blocks with shimmer effect element

- - - - - - - - -

Using SVG via Pattern attribute

- - - - -

Using inline SVG

- - - - - - - - - - - - - - - - diff --git a/packages/web-components/src/skeleton/index.ts b/packages/web-components/src/skeleton/index.ts deleted file mode 100644 index 446e17ee58d62..0000000000000 --- a/packages/web-components/src/skeleton/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Skeleton, skeletonTemplate as template } from '@microsoft/fast-foundation'; -import { skeletonStyles as styles } from './skeleton.styles'; - -/** - * The Fluent Skeleton Element. Implements {@link @microsoft/fast-foundation#Skeleton}, - * {@link @microsoft/fast-foundation#skeletonTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentSkeleton = Skeleton.compose({ - baseName: 'skeleton', - template, - styles, -}); - -/** - * Styles for Skeleton - * @public - */ -export const skeletonStyles = styles; - -/** - * Skeleton base class - * @public - */ -export { Skeleton }; diff --git a/packages/web-components/src/skeleton/skeleton.stories.ts b/packages/web-components/src/skeleton/skeleton.stories.ts deleted file mode 100644 index 7996f379f6e62..0000000000000 --- a/packages/web-components/src/skeleton/skeleton.stories.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { fluentSkeleton } from './index'; - -export default { - title: 'Components/Skeleton', - component: fluentSkeleton, - argTypes: { - shape: { - defaultValue: 'rect', - options: ['circle', 'rect'], - control: { type: 'radio' }, - }, - shimmer: { - control: { type: 'boolean' }, - }, - }, -}; - -const SkeletonTemplate = ({ shape, shimmer }) => ` - -`; - -export const Skeleton = SkeletonTemplate.bind({}); - -Skeleton.args = { - shape: 'rect', - shimmer: false, -}; - -const example = ` - -`; - -Skeleton.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/skeleton/skeleton.styles.ts b/packages/web-components/src/skeleton/skeleton.styles.ts deleted file mode 100644 index 86f7ff6f5548c..0000000000000 --- a/packages/web-components/src/skeleton/skeleton.styles.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { display, ElementDefinitionContext, forcedColorsStylesheetBehavior, FoundationElementDefinition } from '@microsoft/fast-foundation'; -import { SystemColors } from "@microsoft/fast-web-utilities"; -import { controlCornerRadius, neutralFillSecondaryHover, neutralFillSecondaryRest } from '../design-tokens'; - -export const skeletonStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - ${display('block')} :host { - --skeleton-fill-default: ${neutralFillSecondaryRest}; - overflow: hidden; - width: 100%; - position: relative; - background-color: var(--skeleton-fill, var(--skeleton-fill-default)); - --skeleton-animation-gradient-default: linear-gradient( - 270deg, - var(--skeleton-fill, var(--skeleton-fill-default)) 0%, - ${neutralFillSecondaryHover} 51%, - var(--skeleton-fill, var(--skeleton-fill-default)) 100% - ); - --skeleton-animation-timing-default: ease-in-out; - } - - :host(.rect) { - border-radius: calc(${controlCornerRadius} * 1px); - } - - :host(.circle) { - border-radius: 100%; - overflow: hidden; - } - - object { - position: absolute; - width: 100%; - height: auto; - z-index: 2; - } - - object img { - width: 100%; - height: auto; - } - - ${display('block')} span.shimmer { - position: absolute; - width: 100%; - height: 100%; - background-image: var(--skeleton-animation-gradient, var(--skeleton-animation-gradient-default)); - background-size: 0px 0px / 90% 100%; - background-repeat: no-repeat; - background-color: var(--skeleton-animation-fill, ${neutralFillSecondaryRest}); - animation: shimmer 2s infinite; - animation-timing-function: var(--skeleton-animation-timing, var(--skeleton-timing-default)); - animation-direction: normal; - z-index: 1; - } - - ::slotted(svg) { - z-index: 2; - } - - ::slotted(.pattern) { - width: 100%; - height: 100%; - } - - @keyframes shimmer { - 0% { - transform: translateX(-100%); - } - 100% { - transform: translateX(100%); - } - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host{ - background-color: ${SystemColors.CanvasText}; - } - ` - ) - ); diff --git a/packages/web-components/src/skeleton/skeleton.vscode.definition.json b/packages/web-components/src/skeleton/skeleton.vscode.definition.json deleted file mode 100644 index db8485e7a28a4..0000000000000 --- a/packages/web-components/src/skeleton/skeleton.vscode.definition.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-skeleton", - "title": "Skeleton", - "description": "The Fluent UI skeleton element", - "attributes": [ - { - "name": "fill", - "title": "Fill", - "description": "Indicates the Skeleton should have a filled style", - "type": "boolean", - "required": false - }, - { - "name": "shape", - "title": "Shape", - "description": "The shape of the Skeleton", - "type": "string", - "default": "rect", - "values": [{ "name": "rect" }, { "name": "circle" }], - "required": false - }, - { - "name": "pattern", - "title": "Pattern URL", - "description": "Allows a reference to a hosted asset to be used rather than an inline SVG", - "type": "string", - "required": false - }, - { - "name": "shimmer", - "title": "Shimmer", - "description": "Indicates that the component has an activated shimmer effect", - "type": "boolean", - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The default slot can be used to optionally include inline SVG's rather than a pattern" - } - ] - } - ] -} diff --git a/packages/web-components/src/slider-label/fixtures/slider-label.html b/packages/web-components/src/slider-label/fixtures/slider-label.html deleted file mode 100644 index eaeb9a54f411e..0000000000000 --- a/packages/web-components/src/slider-label/fixtures/slider-label.html +++ /dev/null @@ -1,24 +0,0 @@ -
-

Default

-
- basic -
-

Disabled

-
- disabled -
-

Hide mark

-
- hide-mark -
-

With position

-
- pos:10 -
-

Vertical

-
- - vert - -
-
diff --git a/packages/web-components/src/slider-label/index.ts b/packages/web-components/src/slider-label/index.ts deleted file mode 100644 index 843d96e1b9a4e..0000000000000 --- a/packages/web-components/src/slider-label/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { SliderLabel, sliderLabelTemplate as template } from '@microsoft/fast-foundation'; -import { sliderLabelStyles as styles } from './slider-label.styles'; - -/** - * The Fluent Slider Label Custom Element. Implements {@link @microsoft/fast-foundation#SliderLabel}, - * {@link @microsoft/fast-foundation#sliderLabelTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentSliderLabel = SliderLabel.compose({ - baseName: 'slider-label', - template, - styles, -}); - -/** - * Styles for SliderLabel - * @public - */ -export const sliderLabelStyles = styles; - -/** - * Slider label base class - * @public - */ -export { SliderLabel }; diff --git a/packages/web-components/src/slider-label/slider-label.stories.ts b/packages/web-components/src/slider-label/slider-label.stories.ts deleted file mode 100644 index a7ff995d7fc3e..0000000000000 --- a/packages/web-components/src/slider-label/slider-label.stories.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { fluentSlider } from '../slider/index'; - -export default { - title: 'Components/Slider Label', - components: fluentSlider, - argTypes: { - disabled: { - control: { type: 'boolean' }, - }, - hideMark: { - control: { type: 'boolean' }, - }, - position: { - control: { type: 'number' }, - }, - }, -}; - -const SliderLabelTemplate = ({ disabled, hideMark, label, orientation, position }) => ` - - ${label} - -`; - -export const SliderLabel = SliderLabelTemplate.bind({}); - -SliderLabel.args = { - hideMark: false, - label: 'Label', -}; - -const example = ` - basic -`; - -SliderLabel.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/slider-label/slider-label.styles.ts b/packages/web-components/src/slider-label/slider-label.styles.ts deleted file mode 100644 index ed587a56c7d9d..0000000000000 --- a/packages/web-components/src/slider-label/slider-label.styles.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { - display, - ElementDefinitionContext, - forcedColorsStylesheetBehavior, - FoundationElementDefinition, -} from '@microsoft/fast-foundation'; -import { designUnit, disabledOpacity, neutralStrokeStrongRest, strokeWidth } from '../design-tokens'; -import { typeRampMinus1 } from '../styles/patterns/type-ramp'; - -export const sliderLabelStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - ${display('block')} :host { - ${typeRampMinus1} - } - .root { - position: absolute; - display: grid; - } - :host(.horizontal) { - align-self: start; - grid-row: 2; - margin-top: -4px; - } - :host(.vertical) { - justify-self: start; - grid-column: 2; - margin-left: 2px; - } - .container { - display: grid; - justify-self: center; - } - :host(.horizontal) .container { - grid-template-rows: auto auto; - grid-template-columns: 0; - } - :host(.vertical) .container { - grid-template-columns: auto auto; - grid-template-rows: 0; - min-width: calc(var(--thumb-size) * 1px); - height: calc(var(--thumb-size) * 1px); - } - .label { - justify-self: center; - align-self: center; - white-space: nowrap; - max-width: 30px; - margin: 2px 0; - } - .mark { - width: calc(${strokeWidth} * 1px); - height: calc(${designUnit} * 1px); - background: ${neutralStrokeStrongRest}; - justify-self: center; - } - :host(.vertical) .mark { - transform: rotate(90deg); - align-self: center; - } - :host(.vertical) .label { - margin-left: calc((${designUnit} / 2) * 2px); - align-self: center; - } - :host(.disabled) { - opacity: ${disabledOpacity}; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - .mark { - forced-color-adjust: none; - background: ${SystemColors.FieldText}; - } - :host(.disabled) { - forced-color-adjust: none; - opacity: 1; - } - :host(.disabled) .label { - color: ${SystemColors.GrayText}; - } - :host(.disabled) .mark { - background: ${SystemColors.GrayText}; - } - `, - ), - ); diff --git a/packages/web-components/src/slider-label/slider-label.vscode.definition.json b/packages/web-components/src/slider-label/slider-label.vscode.definition.json deleted file mode 100644 index 8025ffe6395e6..0000000000000 --- a/packages/web-components/src/slider-label/slider-label.vscode.definition.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-slider-label", - "title": "Slider label", - "description": "The Fluent UI slider-label element", - "attributes": [ - { - "name": "hide-mark", - "title": "Hide mark", - "description": "Hides the tick mark", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Sets the disabled state of the label", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "position", - "title": "Position", - "description": "The position of the label relative to the min and max value of the parent", - "type": "string", - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the slider label" - } - ] - } - ] -} diff --git a/packages/web-components/src/slider/fixtures/slider.html b/packages/web-components/src/slider/fixtures/slider.html deleted file mode 100644 index 86e306c60f694..0000000000000 --- a/packages/web-components/src/slider/fixtures/slider.html +++ /dev/null @@ -1,169 +0,0 @@ -
-

Toggle orientation

-
- - - - 0℃ - 10℃ - 90℃ - 100℃ - -
- -

Defaults

- - - -

horizontal with left offset

- - - -

Vertical with top offset

- - - -

Negative positions

- - -3 - -2 - -1 - 0 - 1 - 2 - 3 - - - -

Min value greater than 0

-
- - 5 - 15 - -
- - -

Text labels

-
- - - 10℃ - 90℃ - -
- - -

Custom labels (rtl)

-
- -
- - 10 - 20 - 40 - 60 - 80 - -
-
- - -

Custom thumb

- - 0 - 10 - 20 - 30 - 40 - 50 - 60 - 70 - 80 - 90 - 100 - - - - - - -

Vertical

- - 0℃ - 10℃ - 90℃ - 100℃ - - - -

Custom labels, hide marks on labels

- - - - - - - 50 - - - - - - - - -

Disabled

- - 0 - 10 - 20 - 30 - 40 - 50 - 60 - 70 - 80 - 90 - 100 - - -

Read Only

- - 0 - 10 - 20 - 30 - 40 - 50 - 60 - 70 - 80 - 90 - 100 - -
diff --git a/packages/web-components/src/slider/index.ts b/packages/web-components/src/slider/index.ts deleted file mode 100644 index 96128b7f5c8c9..0000000000000 --- a/packages/web-components/src/slider/index.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Slider, SliderOptions, sliderTemplate as template } from '@microsoft/fast-foundation'; -import { sliderStyles as styles } from './slider.styles'; - -/** - * The Fluent Slider Custom Element. Implements {@link @microsoft/fast-foundation#(Slider:class)}, - * {@link @microsoft/fast-foundation#sliderTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentSlider = Slider.compose({ - baseName: 'slider', - template, - styles, - thumb: ` -
- `, -}); - -/** - * Styles for Slider - * @public - */ -export const sliderStyles = styles; - -/** - * Slider base class - * @public - */ -export { Slider }; diff --git a/packages/web-components/src/slider/slider.stories.ts b/packages/web-components/src/slider/slider.stories.ts deleted file mode 100644 index b33049a8087ab..0000000000000 --- a/packages/web-components/src/slider/slider.stories.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { fluentSlider } from './index'; - -export default { - title: 'Components/Slider', - component: fluentSlider, - argTypes: { - orientation: { - options: ['horizontal', 'vertical'], - control: { type: 'radio' }, - }, - }, -}; - -const SliderTemplate = ({ orientation }) => ` - - 0℃ - 10℃ - 90℃ - 100℃ - `; - -export const Slider = SliderTemplate.bind({}); - -Slider.args = { - orientation: 'horizontal', -}; - -const example = ` - - 0℃ - 10℃ - 90℃ - 100℃ - -`; - -Slider.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/slider/slider.styles.ts b/packages/web-components/src/slider/slider.styles.ts deleted file mode 100644 index c2a45db00e1f3..0000000000000 --- a/packages/web-components/src/slider/slider.styles.ts +++ /dev/null @@ -1,194 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { - disabledCursor, - display, - ElementDefinitionContext, - focusVisible, - forcedColorsStylesheetBehavior, - SliderOptions, -} from '@microsoft/fast-foundation'; -import { heightNumber } from '../styles'; -import { - accentFillActive, - accentFillHover, - accentFillRest, - controlCornerRadius, - designUnit, - disabledOpacity, - fillColor, - focusStrokeOuter, - neutralFillRest, - neutralFillStrongRest, - neutralStrokeControlActive, - neutralStrokeControlHover, - neutralStrokeControlRest, - neutralStrokeStrongRest, - strokeWidth, -} from '../design-tokens'; - -export const sliderStyles: (context: ElementDefinitionContext, definition: SliderOptions) => ElementStyles = ( - context: ElementDefinitionContext, - definition: SliderOptions, -) => - css` - ${display('inline-grid')} :host { - --thumb-size: calc((${heightNumber} / 2) + ${designUnit} + (${strokeWidth} * 2)); - --thumb-translate: calc(var(--thumb-size) * -0.5 + var(--track-width) / 2); - --track-overhang: calc((${designUnit} / 2) * -1); - --track-width: ${designUnit}; - align-items: center; - width: 100%; - user-select: none; - box-sizing: border-box; - border-radius: calc(${controlCornerRadius} * 1px); - outline: none; - cursor: pointer; - } - :host(.horizontal) .positioning-region { - position: relative; - margin: 0 8px; - display: grid; - grid-template-rows: calc(var(--thumb-size) * 1px) 1fr; - } - :host(.vertical) .positioning-region { - position: relative; - margin: 0 8px; - display: grid; - height: 100%; - grid-template-columns: calc(var(--thumb-size) * 1px) 1fr; - } - :host(:${focusVisible}) .thumb-cursor { - box-shadow: 0 0 0 2px ${fillColor}, 0 0 0 4px ${focusStrokeOuter}; - } - .thumb-container { - position: absolute; - height: calc(var(--thumb-size) * 1px); - width: calc(var(--thumb-size) * 1px); - transition: all 0.2s ease; - } - .thumb-cursor { - display: flex; - position: relative; - border: none; - width: calc(var(--thumb-size) * 1px); - height: calc(var(--thumb-size) * 1px); - background: padding-box linear-gradient(${neutralFillRest}, ${neutralFillRest}), - border-box ${neutralStrokeControlRest}; - border: calc(${strokeWidth} * 1px) solid transparent; - border-radius: 50%; - box-sizing: border-box; - } - .thumb-cursor::after { - content: ''; - display: block; - border-radius: 50%; - width: 100%; - margin: 4px; - background: ${accentFillRest}; - } - :host(:not(.disabled)) .thumb-cursor:hover::after { - background: ${accentFillHover}; - margin: 3px; - } - :host(:not(.disabled)) .thumb-cursor:active::after { - background: ${accentFillActive}; - margin: 5px; - } - :host(:not(.disabled)) .thumb-cursor:hover { - background: padding-box linear-gradient(${neutralFillRest}, ${neutralFillRest}), - border-box ${neutralStrokeControlHover}; - } - :host(:not(.disabled)) .thumb-cursor:active { - background: padding-box linear-gradient(${neutralFillRest}, ${neutralFillRest}), - border-box ${neutralStrokeControlActive}; - } - .track-start { - background: ${accentFillRest}; - position: absolute; - height: 100%; - left: 0; - border-radius: calc(${controlCornerRadius} * 1px); - } - :host(.horizontal) .thumb-container { - transform: translateX(calc(var(--thumb-size) * 0.5px)) translateY(calc(var(--thumb-translate) * 1px)); - } - :host(.vertical) .thumb-container { - transform: translateX(calc(var(--thumb-translate) * 1px)) translateY(calc(var(--thumb-size) * 0.5px)); - } - :host(.horizontal) { - min-width: calc(var(--thumb-size) * 1px); - } - :host(.horizontal) .track { - right: calc(var(--track-overhang) * 1px); - left: calc(var(--track-overhang) * 1px); - align-self: start; - height: calc(var(--track-width) * 1px); - } - :host(.vertical) .track { - top: calc(var(--track-overhang) * 1px); - bottom: calc(var(--track-overhang) * 1px); - width: calc(var(--track-width) * 1px); - height: 100%; - } - .track { - background: ${neutralFillStrongRest}; - border: 1px solid ${neutralStrokeStrongRest}; - border-radius: 2px; - box-sizing: border-box; - position: absolute; - } - :host(.vertical) { - height: 100%; - min-height: calc(${designUnit} * 60px); - min-width: calc(${designUnit} * 20px); - } - :host(.vertical) .track-start { - height: auto; - width: 100%; - top: 0; - } - :host(.disabled), - :host(.readonly) { - cursor: ${disabledCursor}; - } - :host(.disabled) { - opacity: ${disabledOpacity}; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - .thumb-cursor { - forced-color-adjust: none; - border-color: ${SystemColors.FieldText}; - background: ${SystemColors.FieldText}; - } - :host(:not(.disabled)) .thumb-cursor:hover, - :host(:not(.disabled)) .thumb-cursor:active { - background: ${SystemColors.Highlight}; - } - .track { - forced-color-adjust: none; - background: ${SystemColors.FieldText}; - } - .thumb-cursor::after, - :host(:not(.disabled)) .thumb-cursor:hover::after, - :host(:not(.disabled)) .thumb-cursor:active::after { - background: ${SystemColors.Field}; - } - :host(:${focusVisible}) .thumb-cursor { - background: ${SystemColors.Highlight}; - border-color: ${SystemColors.Highlight}; - box-shadow: 0 0 0 1px ${SystemColors.Field}, 0 0 0 3px ${SystemColors.FieldText}; - } - :host(.disabled) { - opacity: 1; - } - :host(.disabled) .track, - :host(.disabled) .thumb-cursor { - forced-color-adjust: none; - background: ${SystemColors.GrayText}; - } - `, - ), - ); diff --git a/packages/web-components/src/slider/slider.vscode.definition.json b/packages/web-components/src/slider/slider.vscode.definition.json deleted file mode 100644 index 64122675d2c8f..0000000000000 --- a/packages/web-components/src/slider/slider.vscode.definition.json +++ /dev/null @@ -1,101 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-slider", - "title": "Slider", - "description": "The Fluent UI slider element", - "attributes": [ - { - "name": "value", - "title": "Value", - "description": "The slider value", - "required": false, - "type": "number" - }, - { - "name": "max", - "title": "Maximum", - "description": "The maximum value", - "type": "string", - "default": false, - "required": false - }, - { - "name": "min", - "title": "Minimum", - "description": "The minimum value", - "type": "string", - "default": false, - "required": false - }, - { - "name": "step", - "title": "Increment", - "description": "Amount to increment or decrement the value by", - "type": "string", - "default": false, - "required": false - }, - { - "name": "orientation", - "title": "Orientation", - "description": "The orientation of the slider", - "default": "horizontal", - "values": [{ "name": "horizontal" }, { "name": "vertical" }], - "required": false, - "type": "string" - }, - { - "name": "name", - "title": "Name", - "description": "This element's value will be surfaced during form submission under the provided name", - "type": "string", - "default": "", - "required": false - }, - { - "name": "required", - "title": "Required", - "description": "Require the field to be completed prior to form submission", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Sets the disabled state of the slider", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "readonly", - "title": "Readonly", - "description": "When true, the control will be immutable by user interaction", - "type": "boolean", - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "Default slotted content of the slider represents its visual labels" - }, - { - "name": "track", - "title": "Track slot", - "description": "Slot to replace the slider track" - }, - { - "name": "thumb", - "title": "Thumb slot", - "description": "Slot to replace the slider thumb" - } - ] - } - ] -} diff --git a/packages/web-components/src/styles/direction.ts b/packages/web-components/src/styles/direction.ts deleted file mode 100644 index eea834faf9c62..0000000000000 --- a/packages/web-components/src/styles/direction.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Behavior, ElementStyles, FASTElement, Subscriber } from '@microsoft/fast-element'; -import { DesignTokenChangeRecord } from '@microsoft/fast-foundation'; -import { Direction } from '@microsoft/fast-web-utilities'; -import { direction as directionDesignToken } from '../design-tokens'; -/** - * Behavior to conditionally apply LTR and RTL stylesheets. To determine which to apply, - * the behavior will use the nearest DesignSystemProvider's 'direction' design system value. - * - * @public - * @example - * ```ts - * import { css } from "@microsoft/fast-element"; - * import { DirectionalStyleSheetBehavior } from "@microsoft/fast-foundation"; - * - * css` - * // ... - * `.withBehaviors(new DirectionalStyleSheetBehavior( - * css`:host { content: "ltr"}`), - * css`:host { content: "rtl"}`), - * ) - * ``` - */ -export class DirectionalStyleSheetBehavior implements Behavior { - private ltr: ElementStyles | null; - private rtl: ElementStyles | null; - private cache: WeakMap = new WeakMap(); - - constructor(ltr: ElementStyles | null, rtl: ElementStyles | null) { - this.ltr = ltr; - this.rtl = rtl; - } - - /** - * @internal - */ - public bind(source: FASTElement & HTMLElement) { - this.attach(source); - } - - /** - * @internal - */ - public unbind(source: FASTElement & HTMLElement) { - const cache = this.cache.get(source); - - if (cache) { - directionDesignToken.unsubscribe(cache); - } - } - - private attach(source: FASTElement & HTMLElement) { - const subscriber = - this.cache.get(source) || new DirectionalStyleSheetBehaviorSubscription(this.ltr, this.rtl, source); - - const value = directionDesignToken.getValueFor(source); - directionDesignToken.subscribe(subscriber); - subscriber.attach(value); - - this.cache.set(source, subscriber); - } -} - -/** - * Subscription for {@link DirectionalStyleSheetBehavior} - */ -class DirectionalStyleSheetBehaviorSubscription implements Subscriber { - private attached: ElementStyles | null = null; - - constructor( - private ltr: ElementStyles | null, - private rtl: ElementStyles | null, - private source: HTMLElement & FASTElement, - ) {} - - public handleChange({ target, token }: DesignTokenChangeRecord) { - this.attach(token.getValueFor(this.source)); - } - - public attach(direction: Direction) { - if (this.attached !== this[direction]) { - if (this.attached !== null) { - this.source.$fastController.removeStyles(this.attached); - } - this.attached = this[direction]; - if (this.attached !== null) { - this.source.$fastController.addStyles(this.attached); - } - } - } -} diff --git a/packages/web-components/src/styles/elevation.ts b/packages/web-components/src/styles/elevation.ts deleted file mode 100644 index 6a83b1fd5ead0..0000000000000 --- a/packages/web-components/src/styles/elevation.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { DesignToken } from '@microsoft/fast-foundation'; -import { Swatch } from '../color/swatch'; - -/** - * Define shadow algorithms. - * - * TODO: The --background-luminance will need to be derived from JavaScript. For now - * this is hard-coded to a 1, the relative luminance of pure white. - * https://github.com/microsoft/fast/issues/2778 - * opacity was `calc(.11 * (2 - var(--background-luminance, 1)))` - * - * @internal - * @deprecated Use elevationShadow design token - */ -export const ambientShadow = '0 0 2px rgba(0, 0, 0, 0.14)'; - -/** - * @internal - * @deprecated Use elevationShadow design token - */ -export const directionalShadow = '0 calc(var(--elevation) * 0.5px) calc((var(--elevation) * 1px)) rgba(0, 0, 0, 0.2)'; - -/** - * Applies the box-shadow CSS rule set to the elevation formula. - * Control this formula with the --elevation CSS Custom Property - * by setting --elevation to a number. - * - * @public - * @deprecated Use elevationShadow design token - */ -export const elevation = `box-shadow: ${ambientShadow}, ${directionalShadow};`; - -/** @public */ -export interface ElevationRecipe { - evaluate(element: HTMLElement, size: number, reference?: Swatch): string; -} - -/** - * @public - */ -export const elevationShadowRecipe = DesignToken.create({ - name: 'elevation-shadow', - cssCustomPropertyName: null, -}).withDefault({ - evaluate: (element: HTMLElement, size: number, reference?: Swatch): string => { - let ambientOpacity = 0.12; - let directionalOpacity = 0.14; - - if (size > 16) { - ambientOpacity = 0.2; - directionalOpacity = 0.24; - } - - const ambient = `0 0 2px rgba(0, 0, 0, ${ambientOpacity})`; - const directional = `0 calc(${size} * 0.5px) calc((${size} * 1px)) rgba(0, 0, 0, ${directionalOpacity})`; - return `${ambient}, ${directional}`; - }, -}); - -/** @public */ -export const elevationShadowCardRestSize = DesignToken.create('elevation-shadow-card-rest-size').withDefault(4); -/** @public */ -export const elevationShadowCardHoverSize = DesignToken.create('elevation-shadow-card-hover-size').withDefault( - 8, -); -/** @public */ -export const elevationShadowCardActiveSize = DesignToken.create( - 'elevation-shadow-card-active-size', -).withDefault(0); -/** @public */ -export const elevationShadowCardFocusSize = DesignToken.create('elevation-shadow-card-focus-size').withDefault( - 8, -); -/** @public */ -export const elevationShadowCardRest = DesignToken.create('elevation-shadow-card-rest').withDefault( - (element: HTMLElement) => - elevationShadowRecipe.getValueFor(element).evaluate(element, elevationShadowCardRestSize.getValueFor(element)), -); -/** @public */ -export const elevationShadowCardHover = DesignToken.create('elevation-shadow-card-hover').withDefault( - (element: HTMLElement) => - elevationShadowRecipe.getValueFor(element).evaluate(element, elevationShadowCardHoverSize.getValueFor(element)), -); -/** @public */ -export const elevationShadowCardActive = DesignToken.create('elevation-shadow-card-active').withDefault( - (element: HTMLElement) => - elevationShadowRecipe.getValueFor(element).evaluate(element, elevationShadowCardActiveSize.getValueFor(element)), -); -/** @public */ -export const elevationShadowCardFocus = DesignToken.create('elevation-shadow-card-focus').withDefault( - (element: HTMLElement) => - elevationShadowRecipe.getValueFor(element).evaluate(element, elevationShadowCardFocusSize.getValueFor(element)), -); - -/** @public */ -export const elevationShadowTooltipSize = DesignToken.create('elevation-shadow-tooltip-size').withDefault(16); -/** @public */ -export const elevationShadowTooltip = DesignToken.create('elevation-shadow-tooltip').withDefault( - (element: HTMLElement) => - elevationShadowRecipe.getValueFor(element).evaluate(element, elevationShadowTooltipSize.getValueFor(element)), -); - -/** @public */ -export const elevationShadowFlyoutSize = DesignToken.create('elevation-shadow-flyout-size').withDefault(32); -/** @public */ -export const elevationShadowFlyout = DesignToken.create('elevation-shadow-flyout').withDefault( - (element: HTMLElement) => - elevationShadowRecipe.getValueFor(element).evaluate(element, elevationShadowFlyoutSize.getValueFor(element)), -); - -/** @public */ -export const elevationShadowDialogSize = DesignToken.create('elevation-shadow-dialog-size').withDefault(128); -/** @public */ -export const elevationShadowDialog = DesignToken.create('elevation-shadow-dialog').withDefault( - (element: HTMLElement) => - elevationShadowRecipe.getValueFor(element).evaluate(element, elevationShadowDialogSize.getValueFor(element)), -); diff --git a/packages/web-components/src/styles/focus.ts b/packages/web-components/src/styles/focus.ts deleted file mode 100644 index cb5d22389a7e7..0000000000000 --- a/packages/web-components/src/styles/focus.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { cssPartial } from '@microsoft/fast-element'; -import { focusStrokeOuter, focusStrokeWidth, strokeWidth } from '../design-tokens'; - -/** - * Partial CSS for the focus treatment for most typical sized components like Button, Menu Item, etc. - * - * @public - */ -export const focusTreatmentBase = cssPartial` - outline: calc(${focusStrokeWidth} * 1px) solid ${focusStrokeOuter}; - outline-offset: calc(${focusStrokeWidth} * -1px); -`; - -/** - * Partial CSS for the focus treatment for tighter components with spacing constraints, like Checkbox - * and Radio, or plain text like Hypertext appearance Anchor or Breadcrumb Item. - * - * @public - */ -export const focusTreatmentTight = cssPartial` - outline: calc(${focusStrokeWidth} * 1px) solid ${focusStrokeOuter}; - outline-offset: calc(${strokeWidth} * 1px); -`; diff --git a/packages/web-components/src/styles/index.ts b/packages/web-components/src/styles/index.ts deleted file mode 100644 index a7def19ce9136..0000000000000 --- a/packages/web-components/src/styles/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './direction'; -export * from './elevation'; -export * from './focus'; -export * from './patterns/'; -export * from './size'; diff --git a/packages/web-components/src/styles/patterns/button.styles.ts b/packages/web-components/src/styles/patterns/button.styles.ts deleted file mode 100644 index b64d5fa6a0570..0000000000000 --- a/packages/web-components/src/styles/patterns/button.styles.ts +++ /dev/null @@ -1,538 +0,0 @@ -import { css } from '@microsoft/fast-element'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { - display, - ElementDefinitionContext, - focusVisible, - forcedColorsStylesheetBehavior, - FoundationElementDefinition, -} from '@microsoft/fast-foundation'; -import { heightNumber } from '../size'; -import { - accentFillActive, - accentFillHover, - accentFillRest, - accentForegroundActive, - accentForegroundHover, - accentForegroundRest, - accentStrokeControlActive, - accentStrokeControlHover, - accentStrokeControlRest, - controlCornerRadius, - density, - designUnit, - focusStrokeInner, - focusStrokeWidth, - foregroundOnAccentActive, - foregroundOnAccentHover, - foregroundOnAccentRest, - neutralFillActive, - neutralFillHover, - neutralFillRest, - neutralFillStealthActive, - neutralFillStealthHover, - neutralFillStealthRest, - neutralForegroundRest, - neutralStrokeActive, - neutralStrokeControlActive, - neutralStrokeControlHover, - neutralStrokeControlRest, - neutralStrokeHover, - neutralStrokeRest, - strokeWidth, -} from '../../design-tokens'; -import { typeRampBase } from '../../styles/patterns/type-ramp'; -import { focusTreatmentBase, focusTreatmentTight } from '../focus'; - -/** - * The base styles for button controls, without `appearance` visual differences. - * - * @internal - */ -export const baseButtonStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - interactivitySelector: string, - nonInteractivitySelector: string = '[disabled]', -) => - css` - ${display('inline-flex')} - - :host { - position: relative; - box-sizing: border-box; - ${typeRampBase} - height: calc(${heightNumber} * 1px); - min-width: calc(${heightNumber} * 1px); - color: ${neutralForegroundRest}; - border-radius: calc(${controlCornerRadius} * 1px); - fill: currentcolor; - } - - .control { - border: calc(${strokeWidth} * 1px) solid transparent; - flex-grow: 1; - box-sizing: border-box; - display: inline-flex; - justify-content: center; - align-items: center; - padding: 0 calc((10 + (${designUnit} * 2 * ${density})) * 1px); - white-space: nowrap; - outline: none; - text-decoration: none; - color: inherit; - border-radius: inherit; - fill: inherit; - font-family: inherit; - } - - .control, - .end, - .start { - font: inherit; - } - - .control.icon-only { - padding: 0; - line-height: 0; - } - - .control:${focusVisible} { - ${focusTreatmentBase} - } - - .control::-moz-focus-inner { - border: 0; - } - - .content { - pointer-events: none; - } - - .start, - .end { - display: flex; - pointer-events: none; - } - - .start { - margin-inline-end: 11px; - } - - .end { - margin-inline-start: 11px; - } - `; - -/** - * @internal - */ -export const NeutralButtonStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - interactivitySelector: string, - nonInteractivitySelector: string = '[disabled]', -) => - css` - .control { - background: padding-box linear-gradient(${neutralFillRest}, ${neutralFillRest}), - border-box ${neutralStrokeControlRest}; - } - - :host(${interactivitySelector}:hover) .control { - background: padding-box linear-gradient(${neutralFillHover}, ${neutralFillHover}), - border-box ${neutralStrokeControlHover}; - } - - :host(${interactivitySelector}:active) .control { - background: padding-box linear-gradient(${neutralFillActive}, ${neutralFillActive}), - border-box ${neutralStrokeControlActive}; - } - - :host(${nonInteractivitySelector}) .control { - background: padding-box linear-gradient(${neutralFillRest}, ${neutralFillRest}), - border-box ${neutralStrokeRest}; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - .control { - background: ${SystemColors.ButtonFace}; - border-color: ${SystemColors.ButtonText}; - color: ${SystemColors.ButtonText}; - } - - :host(${interactivitySelector}:hover) .control, - :host(${interactivitySelector}:active) .control { - forced-color-adjust: none; - background: ${SystemColors.HighlightText}; - border-color: ${SystemColors.Highlight}; - color: ${SystemColors.Highlight}; - } - - :host(${nonInteractivitySelector}) .control { - background: transparent; - border-color: ${SystemColors.GrayText}; - color: ${SystemColors.GrayText}; - } - - .control:${focusVisible} { - outline-color: ${SystemColors.CanvasText}; - } - - :host([href]) .control { - background: transparent; - border-color: ${SystemColors.LinkText}; - color: ${SystemColors.LinkText}; - } - - :host([href]:hover) .control, - :host([href]:active) .control { - background: transparent; - border-color: ${SystemColors.CanvasText}; - color: ${SystemColors.CanvasText}; - } - `, - ), - ); - -/** - * @internal - */ -export const AccentButtonStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - interactivitySelector: string, - nonInteractivitySelector: string = '[disabled]', -) => - css` - .control { - background: padding-box linear-gradient(${accentFillRest}, ${accentFillRest}), - border-box ${accentStrokeControlRest}; - color: ${foregroundOnAccentRest}; - } - - :host(${interactivitySelector}:hover) .control { - background: padding-box linear-gradient(${accentFillHover}, ${accentFillHover}), - border-box ${accentStrokeControlHover}; - color: ${foregroundOnAccentHover}; - } - - :host(${interactivitySelector}:active) .control { - background: padding-box linear-gradient(${accentFillActive}, ${accentFillActive}), - border-box ${accentStrokeControlActive}; - color: ${foregroundOnAccentActive}; - } - - :host(${nonInteractivitySelector}) .control { - background: ${accentFillRest}; - } - - .control:${focusVisible} { - box-shadow: 0 0 0 calc(${focusStrokeWidth} * 1px) ${focusStrokeInner} inset !important; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - .control { - forced-color-adjust: none; - background: ${SystemColors.Highlight}; - color: ${SystemColors.HighlightText}; - } - - :host(${interactivitySelector}:hover) .control, - :host(${interactivitySelector}:active) .control { - background: ${SystemColors.HighlightText}; - border-color: ${SystemColors.Highlight}; - color: ${SystemColors.Highlight}; - } - - :host(${nonInteractivitySelector}) .control { - background: transparent; - border-color: ${SystemColors.GrayText}; - color: ${SystemColors.GrayText}; - } - - .control:${focusVisible} { - outline-color: ${SystemColors.CanvasText}; - box-shadow: 0 0 0 calc(${focusStrokeWidth} * 1px) ${SystemColors.HighlightText} inset !important; - } - - :host([href]) .control { - background: ${SystemColors.LinkText}; - color: ${SystemColors.HighlightText}; - } - - :host([href]:hover) .control, - :host([href]:active) .control { - background: ${SystemColors.ButtonFace}; - border-color: ${SystemColors.LinkText}; - color: ${SystemColors.LinkText}; - } - `, - ), - ); - -/** - * @internal - */ -export const HypertextStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - interactivitySelector: string, - nonInteractivitySelector: string = '[disabled]', -) => - css` - :host { - height: auto; - font-family: inherit; - font-size: inherit; - line-height: inherit; - min-width: 0; - } - - .control { - display: inline; - padding: 0; - border: none; - box-shadow: none; - line-height: 1; - } - - :host(${interactivitySelector}) .control { - color: ${accentForegroundRest}; - text-decoration: underline 1px; - } - - :host(${interactivitySelector}:hover) .control { - color: ${accentForegroundHover}; - text-decoration: none; - } - - :host(${interactivitySelector}:active) .control { - color: ${accentForegroundActive}; - text-decoration: none; - } - - .control:${focusVisible} { - ${focusTreatmentTight} - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host(${interactivitySelector}) .control { - color: ${SystemColors.LinkText}; - } - - :host(${interactivitySelector}:hover) .control, - :host(${interactivitySelector}:active) .control { - color: ${SystemColors.CanvasText}; - } - - .control:${focusVisible} { - outline-color: ${SystemColors.CanvasText}; - } - `, - ), - ); - -/** - * @internal - */ -export const LightweightButtonStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - interactivitySelector: string, - nonInteractivitySelector: string = '[disabled]', -) => - css` - :host { - color: ${accentForegroundRest}; - } - - .control { - background: ${neutralFillStealthRest}; - } - - :host(${interactivitySelector}:hover) .control { - background: ${neutralFillStealthHover}; - color: ${accentForegroundHover}; - } - - :host(${interactivitySelector}:active) .control { - background: ${neutralFillStealthActive}; - color: ${accentForegroundActive}; - } - - :host(${nonInteractivitySelector}) .control { - background: ${neutralFillStealthRest}; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host { - color: ${SystemColors.ButtonText}; - } - - .control { - forced-color-adjust: none; - background: transparent; - } - - :host(${interactivitySelector}:hover) .control, - :host(${interactivitySelector}:active) .control { - background: transparent; - border-color: ${SystemColors.ButtonText}; - color: ${SystemColors.ButtonText}; - } - - :host(${nonInteractivitySelector}) .control { - background: transparent; - color: ${SystemColors.GrayText}; - } - - .control:${focusVisible} { - outline-color: ${SystemColors.CanvasText}; - } - - :host([href]) .control { - color: ${SystemColors.LinkText}; - } - - :host([href]:hover) .control, - :host([href]:active) .control { - border-color: ${SystemColors.LinkText}; - color: ${SystemColors.LinkText}; - } - `, - ), - ); - -/** - * @internal - */ -export const OutlineButtonStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - interactivitySelector: string, - nonInteractivitySelector: string = '[disabled]', -) => - css` - .control { - background: transparent !important; - border-color: ${neutralStrokeRest}; - } - - :host(${interactivitySelector}:hover) .control { - border-color: ${neutralStrokeHover}; - } - - :host(${interactivitySelector}:active) .control { - border-color: ${neutralStrokeActive}; - } - - :host(${nonInteractivitySelector}) .control { - background: transparent !important; - border-color: ${neutralStrokeRest}; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - .control { - border-color: ${SystemColors.ButtonText}; - color: ${SystemColors.ButtonText}; - } - - :host(${interactivitySelector}:hover) .control, - :host(${interactivitySelector}:active) .control { - background: ${SystemColors.HighlightText}; - border-color: ${SystemColors.Highlight}; - color: ${SystemColors.Highlight}; - } - - :host(${nonInteractivitySelector}) .control { - border-color: ${SystemColors.GrayText}; - color: ${SystemColors.GrayText}; - } - - .control:${focusVisible} { - outline-color: ${SystemColors.CanvasText}; - } - - :host([href]) .control { - border-color: ${SystemColors.LinkText}; - color: ${SystemColors.LinkText}; - } - - :host([href]:hover) .control, - :host([href]:active) .control { - border-color: ${SystemColors.CanvasText}; - color: ${SystemColors.CanvasText}; - } - `, - ), - ); - -/** - * @internal - */ -export const StealthButtonStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - interactivitySelector: string, - nonInteractivitySelector: string = '[disabled]', -) => - css` - .control { - background: ${neutralFillStealthRest}; - } - - :host(${interactivitySelector}:hover) .control { - background: ${neutralFillStealthHover}; - } - - :host(${interactivitySelector}:active) .control { - background: ${neutralFillStealthActive}; - } - - :host(${nonInteractivitySelector}) .control { - background: ${neutralFillStealthRest}; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - .control { - forced-color-adjust: none; - background: transparent; - color: ${SystemColors.ButtonText}; - } - - :host(${interactivitySelector}:hover) .control, - :host(${interactivitySelector}:active) .control { - background: transparent; - border-color: ${SystemColors.ButtonText}; - color: ${SystemColors.ButtonText}; - } - - :host(${nonInteractivitySelector}) .control { - background: transparent; - color: ${SystemColors.GrayText}; - } - - .control:${focusVisible} { - outline-color: ${SystemColors.CanvasText}; - } - - :host([href]) .control { - color: ${SystemColors.LinkText}; - } - - :host([href]:hover) .control, - :host([href]:active) .control { - background: transparent; - border-color: ${SystemColors.LinkText}; - color: ${SystemColors.LinkText}; - } - `, - ), - ); diff --git a/packages/web-components/src/styles/patterns/index.ts b/packages/web-components/src/styles/patterns/index.ts deleted file mode 100644 index 2d14765468d77..0000000000000 --- a/packages/web-components/src/styles/patterns/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './button.styles'; -export * from './input.styles'; -export * from './type-ramp'; diff --git a/packages/web-components/src/styles/patterns/input.styles.ts b/packages/web-components/src/styles/patterns/input.styles.ts deleted file mode 100644 index ed90312029c31..0000000000000 --- a/packages/web-components/src/styles/patterns/input.styles.ts +++ /dev/null @@ -1,311 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - DesignToken, - disabledCursor, - ElementDefinitionContext, - FoundationElementDefinition, -} from '@microsoft/fast-foundation'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { Swatch } from '../../color/swatch'; -import { - accentFillRest, - controlCornerRadius, - disabledOpacity, - focusStrokeWidth, - neutralFillInputFocus, - neutralFillInputHover, - neutralFillInputRecipe, - neutralFillInputRest, - neutralFillSecondaryFocus, - neutralFillSecondaryHover, - neutralFillSecondaryRecipe, - neutralFillSecondaryRest, - neutralForegroundHintRecipe, - neutralForegroundRest, - neutralStrokeInputHover, - neutralStrokeInputRest, - neutralStrokeRest, - strokeWidth, -} from '../../design-tokens'; -import { typeRampBase } from '../patterns/type-ramp'; -import { heightNumber } from '../size'; -import { focusTreatmentBase } from '../focus'; - -const placeholderRest = DesignToken.create('input-placeholder-rest').withDefault((target: HTMLElement) => { - const baseRecipe = neutralFillInputRecipe.getValueFor(target); - const hintRecipe = neutralForegroundHintRecipe.getValueFor(target); - return hintRecipe.evaluate(target, baseRecipe.evaluate(target).rest); -}); - -const placeholderHover = DesignToken.create('input-placeholder-hover').withDefault((target: HTMLElement) => { - const baseRecipe = neutralFillInputRecipe.getValueFor(target); - const hintRecipe = neutralForegroundHintRecipe.getValueFor(target); - return hintRecipe.evaluate(target, baseRecipe.evaluate(target).hover); -}); - -const filledPlaceholderRest = DesignToken.create('input-filled-placeholder-rest').withDefault( - (target: HTMLElement) => { - const baseRecipe = neutralFillSecondaryRecipe.getValueFor(target); - const hintRecipe = neutralForegroundHintRecipe.getValueFor(target); - return hintRecipe.evaluate(target, baseRecipe.evaluate(target).rest); - }, -); - -const filledPlaceholderHover = DesignToken.create('input-filled-placeholder-hover').withDefault( - (target: HTMLElement) => { - const baseRecipe = neutralFillSecondaryRecipe.getValueFor(target); - const hintRecipe = neutralForegroundHintRecipe.getValueFor(target); - return hintRecipe.evaluate(target, baseRecipe.evaluate(target).hover); - }, -); - -/** - * The base styles for input controls, without `appearance` visual differences. - * - * @internal - */ -export const baseInputStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - logicalControlSelector: string, -) => ElementStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - logicalControlSelector: string, -) => css` - :host { - ${typeRampBase} - color: ${neutralForegroundRest}; - fill: currentcolor; - user-select: none; - position: relative; - } - - ${logicalControlSelector} { - box-sizing: border-box; - position: relative; - color: inherit; - border: calc(${strokeWidth} * 1px) solid transparent; - border-radius: calc(${controlCornerRadius} * 1px); - height: calc(${heightNumber} * 1px); - font-family: inherit; - font-size: inherit; - line-height: inherit; - } - - .control { - width: 100%; - outline: none; - } - - .label { - display: block; - color: ${neutralForegroundRest}; - cursor: pointer; - ${typeRampBase} - margin-bottom: 4px; - } - - .label__hidden { - display: none; - visibility: hidden; - } - - :host([disabled]) ${logicalControlSelector}, - :host([readonly]) ${logicalControlSelector}, - :host([disabled]) .label, - :host([readonly]) .label, - :host([disabled]) .control, - :host([readonly]) .control { - cursor: ${disabledCursor}; - } - - :host([disabled]) { - opacity: ${disabledOpacity}; - } -`; - -/** - * The styles for active and focus interactions for input controls. - * - * @internal - */ -export const inputStateStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - logicalControlSelector: string, -) => ElementStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - logicalControlSelector: string, -) => css` - @media (forced-colors: none) { - :host(:not([disabled]):active)::after { - left: 50%; - width: 40%; - transform: translateX(-50%); - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - } - - :host(:not([disabled]):focus-within)::after { - left: 0; - width: 100%; - transform: none; - } - - :host(:not([disabled]):active)::after, - :host(:not([disabled]):focus-within:not(:active))::after { - content: ''; - position: absolute; - height: calc(${focusStrokeWidth} * 1px); - bottom: 0; - border-bottom: calc(${focusStrokeWidth} * 1px) solid ${accentFillRest}; - border-bottom-left-radius: calc(${controlCornerRadius} * 1px); - border-bottom-right-radius: calc(${controlCornerRadius} * 1px); - z-index: 2; - transition: all 300ms cubic-bezier(0.1, 0.9, 0.2, 1); - } - } -`; - -/** - * The visual styles for inputs with `appearance='outline'`. - * - * @internal - */ - export const inputOutlineStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - logicalControlSelector: string, - interactivitySelector?: string, -) => ElementStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - logicalControlSelector: string, - interactivitySelector: string = ':not([disabled]):not(:focus-within)', -) => css` - ${logicalControlSelector} { - background: padding-box linear-gradient(${neutralFillInputRest}, ${neutralFillInputRest}), - border-box ${neutralStrokeInputRest}; - } - - :host(${interactivitySelector}:hover) ${logicalControlSelector} { - background: padding-box linear-gradient(${neutralFillInputHover}, ${neutralFillInputHover}), - border-box ${neutralStrokeInputHover}; - } - - :host(:not([disabled]):focus-within) ${logicalControlSelector} { - background: padding-box linear-gradient(${neutralFillInputFocus}, ${neutralFillInputFocus}), - border-box ${neutralStrokeInputRest}; - } - - :host([disabled]) ${logicalControlSelector} { - background: padding-box linear-gradient(${neutralFillInputRest}, ${neutralFillInputRest}), - border-box ${neutralStrokeRest}; - } - - .control::placeholder { - color: ${placeholderRest}; - } - - :host(${interactivitySelector}:hover) .control::placeholder { - color: ${placeholderHover}; - } -`; - -/** - * The visual styles for inputs with `appearance='filled'`. - * - * @internal - */ -export const inputFilledStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - logicalControlSelector: string, - interactivitySelector?: string, -) => ElementStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - logicalControlSelector: string, - interactivitySelector: string = ':not([disabled]):not(:focus-within)', -) => css` - ${logicalControlSelector} { - background: ${neutralFillSecondaryRest}; - } - - :host(${interactivitySelector}:hover) ${logicalControlSelector} { - background: ${neutralFillSecondaryHover}; - } - - :host(:not([disabled]):focus-within) ${logicalControlSelector} { - background: ${neutralFillSecondaryFocus}; - } - - :host([disabled]) ${logicalControlSelector} { - background: ${neutralFillSecondaryRest}; - } - - .control::placeholder { - color: ${filledPlaceholderRest}; - } - - :host(${interactivitySelector}:hover) .control::placeholder { - color: ${filledPlaceholderHover}; - } -`; - -/** - * @internal - */ -export const inputForcedColorStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - logicalControlSelector: string, - interactivitySelector?: string, -) => ElementStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, - logicalControlSelector: string, - interactivitySelector: string = ':not([disabled]):not(:focus-within)', -) => css` - :host { - color: ${SystemColors.ButtonText}; - } - - ${logicalControlSelector} { - background: ${SystemColors.ButtonFace}; - border-color: ${SystemColors.ButtonText}; - } - - :host(${interactivitySelector}:hover) ${logicalControlSelector}, - :host(:not([disabled]):focus-within) ${logicalControlSelector} { - border-color: ${SystemColors.Highlight}; - } - - :host([disabled]) ${logicalControlSelector} { - opacity: 1; - background: ${SystemColors.ButtonFace}; - border-color: ${SystemColors.GrayText}; - } - - .control::placeholder, - :host(${interactivitySelector}:hover) .control::placeholder { - color: ${SystemColors.CanvasText}; - } - - :host(:not([disabled]):focus) ${logicalControlSelector} { - ${focusTreatmentBase} - outline-color: ${SystemColors.Highlight}; - } - - :host([disabled]) { - opacity: 1; - color: ${SystemColors.GrayText}; - } - - :host([disabled]) ::placeholder, - :host([disabled]) ::-webkit-input-placeholder { - color: ${SystemColors.GrayText}; - } -`; diff --git a/packages/web-components/src/styles/patterns/type-ramp.ts b/packages/web-components/src/styles/patterns/type-ramp.ts deleted file mode 100644 index 8d197cf72e7db..0000000000000 --- a/packages/web-components/src/styles/patterns/type-ramp.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { cssPartial } from '@microsoft/fast-element'; -import { - bodyFont, - typeRampBaseFontSize, - typeRampBaseFontVariations, - typeRampBaseLineHeight, - typeRampMinus1FontSize, - typeRampMinus1FontVariations, - typeRampMinus1LineHeight, - typeRampMinus2FontSize, - typeRampMinus2FontVariations, - typeRampMinus2LineHeight, - typeRampPlus1FontSize, - typeRampPlus1FontVariations, - typeRampPlus1LineHeight, - typeRampPlus2FontSize, - typeRampPlus2FontVariations, - typeRampPlus2LineHeight, - typeRampPlus3FontSize, - typeRampPlus3FontVariations, - typeRampPlus3LineHeight, - typeRampPlus4FontSize, - typeRampPlus4FontVariations, - typeRampPlus4LineHeight, - typeRampPlus5FontSize, - typeRampPlus5FontVariations, - typeRampPlus5LineHeight, - typeRampPlus6FontSize, - typeRampPlus6FontVariations, - typeRampPlus6LineHeight, -} from '../../design-tokens'; - -/** @public */ -export const typeRampBase = cssPartial` - font-family: ${bodyFont}; - font-size: ${typeRampBaseFontSize}; - line-height: ${typeRampBaseLineHeight}; - font-weight: initial; - font-variation-settings: ${typeRampBaseFontVariations}; -`; -/** @public */ -export const typeRampMinus1 = cssPartial` - font-family: ${bodyFont}; - font-size: ${typeRampMinus1FontSize}; - line-height: ${typeRampMinus1LineHeight}; - font-weight: initial; - font-variation-settings: ${typeRampMinus1FontVariations}; -`; -/** @public */ -export const typeRampMinus2 = cssPartial` - font-family: ${bodyFont}; - font-size: ${typeRampMinus2FontSize}; - line-height: ${typeRampMinus2LineHeight}; - font-weight: initial; - font-variation-settings: ${typeRampMinus2FontVariations}; -`; -/** @public */ -export const typeRampPlus1 = cssPartial` - font-family: ${bodyFont}; - font-size: ${typeRampPlus1FontSize}; - line-height: ${typeRampPlus1LineHeight}; - font-weight: initial; - font-variation-settings: ${typeRampPlus1FontVariations}; -`; -/** @public */ -export const typeRampPlus2 = cssPartial` - font-family: ${bodyFont}; - font-size: ${typeRampPlus2FontSize}; - line-height: ${typeRampPlus2LineHeight}; - font-weight: initial; - font-variation-settings: ${typeRampPlus2FontVariations}; -`; -/** @public */ -export const typeRampPlus3 = cssPartial` - font-family: ${bodyFont}; - font-size: ${typeRampPlus3FontSize}; - line-height: ${typeRampPlus3LineHeight}; - font-weight: initial; - font-variation-settings: ${typeRampPlus3FontVariations}; -`; -/** @public */ -export const typeRampPlus4 = cssPartial` - font-family: ${bodyFont}; - font-size: ${typeRampPlus4FontSize}; - line-height: ${typeRampPlus4LineHeight}; - font-weight: initial; - font-variation-settings: ${typeRampPlus4FontVariations}; -`; -/** @public */ -export const typeRampPlus5 = cssPartial` - font-family: ${bodyFont}; - font-size: ${typeRampPlus5FontSize}; - line-height: ${typeRampPlus5LineHeight}; - font-weight: initial; - font-variation-settings: ${typeRampPlus5FontVariations}; -`; -/** @public */ -export const typeRampPlus6 = cssPartial` - font-family: ${bodyFont}; - font-size: ${typeRampPlus6FontSize}; - line-height: ${typeRampPlus6LineHeight}; - font-weight: initial; - font-variation-settings: ${typeRampPlus6FontVariations}; -`; diff --git a/packages/web-components/src/styles/size.ts b/packages/web-components/src/styles/size.ts deleted file mode 100644 index 831091ee24408..0000000000000 --- a/packages/web-components/src/styles/size.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { cssPartial } from '@microsoft/fast-element'; -import { baseHeightMultiplier, density, designUnit } from '../design-tokens'; - -/** - * A formula to retrieve the control height. - * Use this as the value of any CSS property that - * accepts a pixel size. - * @public - */ -export const heightNumber = cssPartial`(${baseHeightMultiplier} + ${density}) * ${designUnit}`; diff --git a/packages/web-components/src/switch/fixtures/switch.html b/packages/web-components/src/switch/fixtures/switch.html deleted file mode 100644 index e3cbe0abe908e..0000000000000 --- a/packages/web-components/src/switch/fixtures/switch.html +++ /dev/null @@ -1,42 +0,0 @@ -

Switch

-

Default

-
- - Dark Mode - - New Feature - On - Off - - - Theme - Dark - Light - -
- -

Checked

- - - -

Required

- - - -

Disabled

-
- - label - checked - - checked - On - Off - -
- -

Inline

-Light Speed -Ridiculous Speed -Ludicrous Speed -Plaid Speed diff --git a/packages/web-components/src/switch/index.ts b/packages/web-components/src/switch/index.ts deleted file mode 100644 index 389d92b8ff189..0000000000000 --- a/packages/web-components/src/switch/index.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Switch, SwitchOptions, switchTemplate as template } from '@microsoft/fast-foundation'; -import { switchStyles as styles } from './switch.styles'; - -/** - * The Fluent Switch Custom Element. Implements {@link @microsoft/fast-foundation#Switch}, - * {@link @microsoft/fast-foundation#SwitchTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentSwitch = Switch.compose({ - baseName: 'switch', - template, - styles, - switch: ` - - - - `, -}); - -/** - * Styles for Switch - * @public - */ -export const switchStyles = styles; - -/** - * Switch Base class - * @public - */ -export { Switch }; diff --git a/packages/web-components/src/switch/switch.stories.ts b/packages/web-components/src/switch/switch.stories.ts deleted file mode 100644 index 6370133062847..0000000000000 --- a/packages/web-components/src/switch/switch.stories.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { fluentSwitch } from './index'; - -export default { - title: 'Components/Switch', - component: fluentSwitch, - argTypes: { - checked: { - control: { type: 'boolean' }, - }, - disabled: { - control: { type: 'boolean' }, - }, - }, -}; - -const SwitchTemplate = ({ checked, disabled, label }) => ` -${label} - On - Off - -`; - -export const Switch = SwitchTemplate.bind({}); - -Switch.args = { - label: 'Label', - checked: false, - disabled: false, -}; - -const example = ` - - On - Off - - -`; - -Switch.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/switch/switch.styles.ts b/packages/web-components/src/switch/switch.styles.ts deleted file mode 100644 index 5f6f8c3fa6716..0000000000000 --- a/packages/web-components/src/switch/switch.styles.ts +++ /dev/null @@ -1,253 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { - disabledCursor, - display, - ElementDefinitionContext, - focusVisible, - forcedColorsStylesheetBehavior, - SwitchOptions, -} from '@microsoft/fast-foundation'; -import { DirectionalStyleSheetBehavior, heightNumber } from '../styles'; -import { - accentFillActive, - accentFillHover, - accentFillRest, - bodyFont, - designUnit, - disabledOpacity, - foregroundOnAccentActive, - foregroundOnAccentHover, - foregroundOnAccentRest, - neutralFillInputAltActive, - neutralFillInputAltFocus, - neutralFillInputAltHover, - neutralFillInputAltRest, - neutralForegroundRest, - neutralStrokeStrongActive, - neutralStrokeStrongHover, - neutralStrokeStrongRest, - strokeWidth, -} from '../design-tokens'; -import { typeRampBase } from '../styles/patterns/type-ramp'; -import { focusTreatmentTight } from '../styles/focus'; - -export const switchStyles: (context: ElementDefinitionContext, definition: SwitchOptions) => ElementStyles = ( - context: ElementDefinitionContext, - definition: SwitchOptions, -) => - css` - :host([hidden]) { - display: none; - } - - ${display('inline-flex')} :host { - align-items: center; - outline: none; - font-family: ${bodyFont}; - ${ - /* - * Chromium likes to select label text or the default slot when - * the checkbox is clicked. Maybe there is a better solution here? - */ '' - } user-select: none; - } - - :host(.disabled) { - opacity: ${disabledOpacity}; - } - - :host(.disabled) .label, - :host(.readonly) .label, - :host(.disabled) .switch, - :host(.readonly) .switch, - :host(.disabled) .status-message, - :host(.readonly) .status-message { - cursor: ${disabledCursor}; - } - - .switch { - position: relative; - box-sizing: border-box; - width: calc(((${heightNumber} / 2) + ${designUnit}) * 2px); - height: calc(((${heightNumber} / 2) + ${designUnit}) * 1px); - background: ${neutralFillInputAltRest}; - border-radius: calc(${heightNumber} * 1px); - border: calc(${strokeWidth} * 1px) solid ${neutralStrokeStrongRest}; - cursor: pointer; - } - - :host(:not(.disabled):hover) .switch { - background: ${neutralFillInputAltHover}; - border-color: ${neutralStrokeStrongHover}; - } - - :host(:not(.disabled):active) .switch { - background: ${neutralFillInputAltActive}; - border-color: ${neutralStrokeStrongActive}; - } - - :host(:${focusVisible}) .switch { - ${focusTreatmentTight} - background: ${neutralFillInputAltFocus}; - } - - :host(.checked) .switch { - background: ${accentFillRest}; - border-color: transparent; - } - - :host(.checked:not(.disabled):hover) .switch { - background: ${accentFillHover}; - border-color: transparent; - } - - :host(.checked:not(.disabled):active) .switch { - background: ${accentFillActive}; - border-color: transparent; - } - - slot[name='switch'] { - position: absolute; - display: flex; - border: 1px solid transparent; /* Spacing included in the transform reference box */ - fill: ${neutralForegroundRest}; - transition: all 0.2s ease-in-out; - } - - .status-message { - color: ${neutralForegroundRest}; - cursor: pointer; - ${typeRampBase} - } - - .label__hidden { - display: none; - visibility: hidden; - } - - .label { - color: ${neutralForegroundRest}; - ${typeRampBase} - margin-inline-end: calc(${designUnit} * 2px + 2px); - cursor: pointer; - } - - ::slotted([slot="checked-message"]), - ::slotted([slot="unchecked-message"]) { - margin-inline-start: calc(${designUnit} * 2px + 2px); - } - - :host(.checked) .switch { - background: ${accentFillRest}; - } - - :host(.checked) .switch slot[name='switch'] { - fill: ${foregroundOnAccentRest}; - filter: drop-shadow(0px 1px 1px rgba(0, 0, 0, 0.15)); - } - - :host(.checked:not(.disabled)) .switch:hover { - background: ${accentFillHover}; - } - - :host(.checked:not(.disabled)) .switch:hover slot[name='switch'] { - fill: ${foregroundOnAccentHover}; - } - - :host(.checked:not(.disabled)) .switch:active { - background: ${accentFillActive}; - } - - :host(.checked:not(.disabled)) .switch:active slot[name='switch'] { - fill: ${foregroundOnAccentActive}; - } - - .unchecked-message { - display: block; - } - - .checked-message { - display: none; - } - - :host(.checked) .unchecked-message { - display: none; - } - - :host(.checked) .checked-message { - display: block; - } - `.withBehaviors( - new DirectionalStyleSheetBehavior( - css` - slot[name='switch'] { - left: 0; - } - - :host(.checked) slot[name='switch'] { - left: 100%; - transform: translateX(-100%); - } - `, - css` - slot[name='switch'] { - right: 0; - } - - :host(.checked) slot[name='switch'] { - right: 100%; - transform: translateX(100%); - } - `, - ), - forcedColorsStylesheetBehavior( - css` - :host(:not(.disabled)) .switch slot[name='switch'] { - forced-color-adjust: none; - fill: ${SystemColors.FieldText}; - } - .switch { - background: ${SystemColors.Field}; - border-color: ${SystemColors.FieldText}; - } - :host(.checked) .switch { - background: ${SystemColors.Highlight}; - border-color: ${SystemColors.Highlight}; - } - :host(:not(.disabled):hover) .switch , - :host(:not(.disabled):active) .switch, - :host(.checked:not(.disabled):hover) .switch { - background: ${SystemColors.HighlightText}; - border-color: ${SystemColors.Highlight}; - } - :host(.checked:not(.disabled)) .switch slot[name="switch"] { - fill: ${SystemColors.HighlightText}; - } - :host(.checked:not(.disabled):hover) .switch slot[name='switch'] { - fill: ${SystemColors.Highlight}; - } - :host(:${focusVisible}) .switch { - forced-color-adjust: none; - background: ${SystemColors.Field}; - border-color: ${SystemColors.Highlight}; - outline-color: ${SystemColors.FieldText}; - } - :host(.disabled) { - opacity: 1; - } - :host(.disabled) slot[name='switch'] { - forced-color-adjust: none; - fill: ${SystemColors.GrayText}; - } - :host(.disabled) .switch { - background: ${SystemColors.Field}; - border-color: ${SystemColors.GrayText}; - } - .status-message, - .label { - color: ${SystemColors.FieldText}; - } - `, - ), - ); diff --git a/packages/web-components/src/switch/switch.vscode.definition.json b/packages/web-components/src/switch/switch.vscode.definition.json deleted file mode 100644 index 36d9dc88c9493..0000000000000 --- a/packages/web-components/src/switch/switch.vscode.definition.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-switch", - "title": "Switch", - "description": "The Fluent UI switch element", - "attributes": [ - { - "name": "checked", - "title": "Checked", - "description": "Provides the default checked value", - "required": false, - "type": "boolean" - }, - { - "name": "name", - "title": "Name", - "description": "This element's value will be surfaced during form submission under the provided name", - "type": "string", - "default": "", - "required": false - }, - { - "name": "required", - "title": "Required", - "description": "Require the field to be completed prior to form submission", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Sets the disabled state of the switch", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "readonly", - "title": "Readonly", - "description": "When true, the control will be immutable by user interaction", - "type": "boolean", - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the switch represents its visual label" - }, - { - "name": "checked-message", - "title": "Checked message slot", - "description": "Visible content representing the checked state" - }, - { - "name": "unchecked-message", - "title": "Unchecked message slot", - "description": "Visible content representing the unchecked state" - } - ] - } - ] -} diff --git a/packages/web-components/src/tabs/fixtures/tabs.html b/packages/web-components/src/tabs/fixtures/tabs.html deleted file mode 100644 index b964c5d3aaf6c..0000000000000 --- a/packages/web-components/src/tabs/fixtures/tabs.html +++ /dev/null @@ -1,76 +0,0 @@ -

Tabs

-

Default

- - Tab one - Tab two - Tab three - Tab one content. This is for testing. - Tab two content. This is for testing. - Tab three content. This is for testing. -
Testing
-
-

Vertical

- - Tab one - Tab two - Tab three - Tab one content. This is for testing. - Tab two content. This is for testing. - Tab three content. This is for testing. - -

Supplemental content

- -
- - - -
-
- - - -
- Tab one - Tab two - Tab three - Tab one content. This is for testing. - Tab two content. This is for testing. - Tab three content. This is for testing. -
-

Supplemental content - Vertical

- -
- - - -
-
- - - -
- Tab one - Tab two - Tab three - Tab one content. This is for testing. - Tab two content. This is for testing. - Tab three content. This is for testing. -
-

No active indicator

- - Tab one - Tab two - Tab three - Tab one content. This is for testing. - Tab two content. This is for testing. - Tab three content. This is for testing. - -

No active indicator - Vertical

- - Tab one - Tab two - Tab three - Tab one content. This is for testing. - Tab two content. This is for testing. - Tab three content. This is for testing. - diff --git a/packages/web-components/src/tabs/index.ts b/packages/web-components/src/tabs/index.ts deleted file mode 100644 index ab4708ede7e66..0000000000000 --- a/packages/web-components/src/tabs/index.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Tabs, tabsTemplate as template } from '@microsoft/fast-foundation'; -import { tabsStyles as styles } from './tabs.styles'; - -/** - * The Fluent Tabs Custom Element. Implements {@link @microsoft/fast-foundation#Tabs}, - * {@link @microsoft/fast-foundation#tabsTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentTabs = Tabs.compose({ - baseName: 'tabs', - template, - styles, -}); - -export * from './tab'; -export * from './tab-panel'; - -/** - * Styles for Tabs - * @public - */ -export const tabsStyles = styles; - -/** - * Tabs base class - * @public - */ -export { Tabs }; diff --git a/packages/web-components/src/tabs/tab-panel/index.ts b/packages/web-components/src/tabs/tab-panel/index.ts deleted file mode 100644 index 859f86dd461ba..0000000000000 --- a/packages/web-components/src/tabs/tab-panel/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { TabPanel, tabPanelTemplate as template } from '@microsoft/fast-foundation'; -import { tabPanelStyles as styles } from './tab-panel.styles'; - -/** - * The Fluent Tab Panel Custom Element. Implements {@link @microsoft/fast-foundation#TabPanel}, - * {@link @microsoft/fast-foundation#tabPanelTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentTabPanel = TabPanel.compose({ - baseName: 'tab-panel', - template, - styles, -}); - -/** - * Styles for TabPanel - * @public - */ -export const tabPanelStyles = styles; - -/** - * Tab panel base styles - * @public - */ -export { TabPanel }; diff --git a/packages/web-components/src/tabs/tab-panel/tab-panel.styles.ts b/packages/web-components/src/tabs/tab-panel/tab-panel.styles.ts deleted file mode 100644 index 628ce029a2763..0000000000000 --- a/packages/web-components/src/tabs/tab-panel/tab-panel.styles.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { display, ElementDefinitionContext, FoundationElementDefinition } from '@microsoft/fast-foundation'; -import { density, designUnit } from '../../design-tokens'; -import { typeRampBase } from '../../styles/patterns/type-ramp'; - -export const tabPanelStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => css` - ${display('block')} :host { - box-sizing: border-box; - ${typeRampBase} - padding: 0 calc((6 + (${designUnit} * 2 * ${density})) * 1px); - } -`; diff --git a/packages/web-components/src/tabs/tab-panel/tab-panel.vscode.definition.json b/packages/web-components/src/tabs/tab-panel/tab-panel.vscode.definition.json deleted file mode 100644 index b8637eb42e837..0000000000000 --- a/packages/web-components/src/tabs/tab-panel/tab-panel.vscode.definition.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-tab-panel", - "title": "Tab panel", - "description": "The Fluent UI tab-panel element", - "attributes": [], - "slots": [ - { - "name": "", - "title": "Default slot" - } - ] - } - ] -} diff --git a/packages/web-components/src/tabs/tab/index.ts b/packages/web-components/src/tabs/tab/index.ts deleted file mode 100644 index a64c9af9f23e8..0000000000000 --- a/packages/web-components/src/tabs/tab/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Tab, tabTemplate as template } from '@microsoft/fast-foundation'; -import { tabStyles as styles } from './tab.styles'; - -/** - * The Fluent Tab Custom Element. Implements {@link @microsoft/fast-foundation#Tab}, - * {@link @microsoft/fast-foundation#tabTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentTab = Tab.compose({ - baseName: 'tab', - template, - styles, -}); - -/** - * Styles for Tab - * @public - */ -export const tabStyles = styles; - -/** - * Tab base class - * @public - */ -export { Tab }; diff --git a/packages/web-components/src/tabs/tab/tab.styles.ts b/packages/web-components/src/tabs/tab/tab.styles.ts deleted file mode 100644 index 1f56be856a648..0000000000000 --- a/packages/web-components/src/tabs/tab/tab.styles.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { - display, - ElementDefinitionContext, - focusVisible, - forcedColorsStylesheetBehavior, - FoundationElementDefinition, -} from '@microsoft/fast-foundation'; -import { heightNumber } from '../../styles'; -import { - controlCornerRadius, - density, - designUnit, - neutralForegroundRest, - strokeWidth, -} from '../../design-tokens'; -import { typeRampBase } from '../../styles/patterns/type-ramp'; -import { focusTreatmentBase } from '../../styles/focus'; - -export const tabStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles = - (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - ${display('inline-flex')} :host { - box-sizing: border-box; - ${typeRampBase} - height: calc((${heightNumber} + (${designUnit} * 2)) * 1px); - padding: 0 calc((6 + (${designUnit} * 2 * ${density})) * 1px); - color: ${neutralForegroundRest}; - border-radius: calc(${controlCornerRadius} * 1px); - border: calc(${strokeWidth} * 1px) solid transparent; - align-items: center; - justify-content: center; - grid-row: 1 / 3; - cursor: pointer; - } - - :host([aria-selected='true']) { - z-index: 2; - } - - :host(:hover), - :host(:active) { - color: ${neutralForegroundRest}; - } - - :host(:${focusVisible}) { - ${focusTreatmentBase} - } - - :host(.vertical) { - justify-content: start; - grid-column: 1 / 3; - } - - :host(.vertical[aria-selected='true']) { - z-index: 2; - } - - :host(.vertical:hover), - :host(.vertical:active) { - color: ${neutralForegroundRest}; - } - - :host(.vertical:hover[aria-selected='true']) { - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host { - forced-color-adjust: none; - border-color: transparent; - color: ${SystemColors.ButtonText}; - fill: currentcolor; - } - :host(:hover), - :host(.vertical:hover), - :host([aria-selected='true']:hover) { - background: transparent; - color: ${SystemColors.Highlight}; - fill: currentcolor; - } - :host([aria-selected='true']) { - background: transparent; - color: ${SystemColors.Highlight}; - fill: currentcolor; - } - :host(:${focusVisible}) { - background: transparent; - outline-color: ${SystemColors.ButtonText}; - } - `, - ), - ); diff --git a/packages/web-components/src/tabs/tab/tab.vscode.definition.json b/packages/web-components/src/tabs/tab/tab.vscode.definition.json deleted file mode 100644 index 540fffbb8768f..0000000000000 --- a/packages/web-components/src/tabs/tab/tab.vscode.definition.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-tab", - "title": "Tab", - "description": "The Fluent UI tab element", - "attributes": [], - "slots": [ - { - "name": "", - "title": "Default slot" - } - ] - } - ] -} diff --git a/packages/web-components/src/tabs/tabs.stories.ts b/packages/web-components/src/tabs/tabs.stories.ts deleted file mode 100644 index a2937206e974d..0000000000000 --- a/packages/web-components/src/tabs/tabs.stories.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { fluentTabs } from './index'; - -export default { - title: 'Components/Tabs', - components: fluentTabs, - argTypes: { - activeIndicator: { - control: { type: 'boolean' }, - }, - orientation: { - options: ['horizontal', 'vertical'], - control: { type: 'radio' }, - }, - }, -}; - -const TabsTemplate = ({ activeId, activeIndicator, orientation }) => ` - - Tab one - Tab two - Tab three - - Tab one content. This is for testing. Tab three content. This is for testing. -
- Tab one content. This is for testing. -
- Tab one content. This is for testing. -
- Tab one content. This is for testing. -
- Tab one content. This is for testing. -
- Tab one content. This is for testing. -
- Tab one content. This is for testing. -
- Tab one content. This is for testing. -
- Tab one content. This is for testing. -
- Tab one content. This is for testing. -
- Tab one content. This is for testing. -
- Tab one content. This is for testing. -
- Tab one content. This is for testing. -
-
- Tab two content. This is for testing. - - Tab three content. This is for testing. Tab three content. This is for testing. -
- Tab three content. This is for testing. -
- Tab three content. This is for testing. -
- Tab three content. This is for testing. -
- Tab three content. This is for testing. -
- Tab three content. This is for testing. -
- Tab three content. This is for testing. -
- Tab three content. This is for testing. -
- Tab three content. This is for testing. -
- Tab three content. This is for testing. -
- Tab three content. This is for testing. -
- Tab three content. This is for testing. -
- Tab three content. This is for testing. -
-
-
`; - -export const Tabs = TabsTemplate.bind({}); - -Tabs.args = { - activeId: 'TabTwo', - activeIndicator: true, - orientation: 'horizontal', -}; - -const example = ` - - Tab one - Tab two - Tab three - Tab one content. This is for testing. - Tab two content. This is for testing. - Tab three content. This is for testing. -
Testing
-
-`; - -Tabs.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/tabs/tabs.styles.ts b/packages/web-components/src/tabs/tabs.styles.ts deleted file mode 100644 index 669fea31c9a9f..0000000000000 --- a/packages/web-components/src/tabs/tabs.styles.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { - display, - ElementDefinitionContext, - forcedColorsStylesheetBehavior, - FoundationElementDefinition, -} from '@microsoft/fast-foundation'; -import { - accentFillRest, - controlCornerRadius, - focusStrokeWidth, - neutralForegroundRest, -} from '../design-tokens'; -import { heightNumber } from '../styles'; -import { typeRampBase } from '../styles/patterns/type-ramp'; - -export const tabsStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - ${display('grid')} :host { - box-sizing: border-box; - ${typeRampBase} - color: ${neutralForegroundRest}; - grid-template-columns: auto 1fr auto; - grid-template-rows: auto 1fr; - } - - .tablist { - display: grid; - grid-template-rows: calc(${heightNumber} * 1px); auto; - grid-template-columns: auto; - position: relative; - width: max-content; - align-self: end; - } - - .start, - .end { - align-self: center; - } - - .activeIndicator { - grid-row: 2; - grid-column: 1; - width: 20px; - height: 3px; - border-radius: calc(${controlCornerRadius} * 1px); - justify-self: center; - background: ${accentFillRest}; - } - - .activeIndicatorTransition { - transition: transform 0.2s ease-in-out; - } - - .tabpanel { - grid-row: 2; - grid-column-start: 1; - grid-column-end: 4; - position: relative; - } - - :host(.vertical) { - grid-template-rows: auto 1fr auto; - grid-template-columns: auto 1fr; - } - - :host(.vertical) .tablist { - grid-row-start: 2; - grid-row-end: 2; - display: grid; - grid-template-rows: auto; - grid-template-columns: auto 1fr; - position: relative; - width: max-content; - justify-self: end; - align-self: flex-start; - width: 100%; - } - - :host(.vertical) .tabpanel { - grid-column: 2; - grid-row-start: 1; - grid-row-end: 4; - } - - :host(.vertical) .end { - grid-row: 3; - } - - :host(.vertical) .activeIndicator { - grid-column: 1; - grid-row: 1; - width: 3px; - height: 20px; - margin-inline-start: calc(${focusStrokeWidth} * 1px); - border-radius: calc(${controlCornerRadius} * 1px); - align-self: center; - background: ${accentFillRest}; - } - - :host(.vertical) .activeIndicatorTransition { - transition: transform 0.2s linear; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - .activeIndicator, - :host(.vertical) .activeIndicator { - background: ${SystemColors.Highlight}; - } - `, - ), - ); diff --git a/packages/web-components/src/tabs/tabs.vscode.definition.json b/packages/web-components/src/tabs/tabs.vscode.definition.json deleted file mode 100644 index 6201ef27a777a..0000000000000 --- a/packages/web-components/src/tabs/tabs.vscode.definition.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-tabs", - "title": "Tabs", - "description": "The Fluent UI tabs element", - "attributes": [ - { - "name": "orientation", - "title": "Orientation", - "description": "The orientation of the tabs", - "default": "horizontal", - "required": false, - "type": "string", - "values": [{ "name": "horizontal" }, { "name": "vertical" }] - }, - { - "name": "activeid", - "title": "Active ID", - "description": "The HTML ID of the active tab", - "required": false, - "type": "string" - } - ], - "slots": [ - { - "name": "tab", - "title": "Tab slot", - "description": "Slotted tabs are rendered and associated to their respective tab panel by their order in the DOM" - }, - { - "name": "tabpanel", - "title": "Tabpanel slot", - "description": "Slotted tab panels are rendered and associated to their respective tabs by their order in the DOM" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned before the tablist" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the tablist" - } - ] - } - ] -} diff --git a/packages/web-components/src/text-area/fixtures/text-area.html b/packages/web-components/src/text-area/fixtures/text-area.html deleted file mode 100644 index 6ced3c2536873..0000000000000 --- a/packages/web-components/src/text-area/fixtures/text-area.html +++ /dev/null @@ -1,99 +0,0 @@ -

Text area

-

Default

- - - label - - -

Full Width

- - -

Placeholder

- - - -

Required

- - - -

Rows

- - - -

Cols

- - - -

Rows & Cols

- - - -

Disabled

- - - label - - - - -

Read only

- -label - - -

Autofocus

-autofocus - - -

Resize

-
Both
-resize both - -
Horizontal
-resize horizontal - -
Vertical
-resize vertical - -

Filled

-
Default
- - - label - - -
Placeholder
- - - -
Required
- - - -
Disabled
- - - label - - - - -
Read only
- label - label - - -

Visual vs audio label

- - Visible label - - - -

Audio label only

- - - - - -

With aria-label

- diff --git a/packages/web-components/src/text-area/index.ts b/packages/web-components/src/text-area/index.ts deleted file mode 100644 index 24cd8159a14cc..0000000000000 --- a/packages/web-components/src/text-area/index.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { attr } from '@microsoft/fast-element'; -import { TextArea as FoundationTextArea, textAreaTemplate as template } from '@microsoft/fast-foundation'; -import { textAreaStyles as styles } from './text-area.styles'; - -/** - * Text area appearances - * @public - */ -export type TextAreaAppearance = 'filled' | 'outline'; - -/** - * The Fluent TextArea class - * @internal - */ -export class TextArea extends FoundationTextArea { - /** - * The appearance of the element. - * - * @public - * @remarks - * HTML Attribute: appearance - */ - @attr - public appearance: TextAreaAppearance; - - /** - * @internal - */ - public appearanceChanged(oldValue: TextAreaAppearance, newValue: TextAreaAppearance): void { - if (oldValue !== newValue) { - this.classList.add(newValue); - this.classList.remove(oldValue); - } - } - - /** - * @internal - */ - public connectedCallback(): void { - super.connectedCallback(); - - if (!this.appearance) { - this.appearance = 'outline'; - } - } -} - -/** - * The Fluent Text Area Custom Element. Implements {@link @microsoft/fast-foundation#TextArea}, - * {@link @microsoft/fast-foundation#textAreaTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - * - * {@link https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus | delegatesFocus} - */ -export const fluentTextArea = TextArea.compose({ - baseName: 'text-area', - baseClass: FoundationTextArea, - template, - styles, - shadowOptions: { - delegatesFocus: true, - }, -}); - -/** - * Styles for TextArea - * @public - */ -export const textAreaStyles = styles; diff --git a/packages/web-components/src/text-area/text-area.stories.ts b/packages/web-components/src/text-area/text-area.stories.ts deleted file mode 100644 index 57cdbc0eb30a4..0000000000000 --- a/packages/web-components/src/text-area/text-area.stories.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { fluentTextArea } from './index'; - -export default { - title: 'Components/Text Area', - component: fluentTextArea, - argTypes: { - appearance: { - defaultValue: 'outline', - options: ['filled', 'outline'], - control: { type: 'radio' }, - }, - autoFocus: { - control: { type: 'boolean' }, - }, - disabled: { - control: { type: 'boolean' }, - }, - readonly: { - control: { type: 'boolean' }, - }, - rows: { - control: { type: 'number' }, - }, - cols: { - control: { type: 'number' }, - }, - resize: { - options: ['both', 'horizontal', 'vertical'], - control: { type: 'select' }, - }, - required: { - control: { type: 'boolean' }, - }, - }, -}; - -const TextAreaTemplate = ({ appearance, autoFocus, disabled, placeholder, readonly, rows, cols, resize, required }) => ` -`; - -export const TextArea = TextAreaTemplate.bind({}); - -TextArea.args = { - placeholder: '', - autoFocus: false, - disabled: false, - readonly: false, - required: false, -}; - -const example = ` - -`; - -TextArea.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/text-area/text-area.styles.ts b/packages/web-components/src/text-area/text-area.styles.ts deleted file mode 100644 index 2eded3c4536d3..0000000000000 --- a/packages/web-components/src/text-area/text-area.styles.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - display, - ElementDefinitionContext, - forcedColorsStylesheetBehavior, - FoundationElementDefinition, -} from '@microsoft/fast-foundation'; -import { - baseInputStyles, - heightNumber, - inputFilledStyles, - inputForcedColorStyles, - inputOutlineStyles, - inputStateStyles, -} from '../styles'; -import { appearanceBehavior } from '../utilities/behaviors'; -import { designUnit } from '../design-tokens'; - -const logicalControlSelector: string = '.control'; - -export const textAreaStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => - css` - ${display('inline-flex')} - - ${baseInputStyles(context, definition, logicalControlSelector)} - - ${inputStateStyles(context, definition, logicalControlSelector)} - - :host { - flex-direction: column; - vertical-align: bottom; - } - - .control { - height: calc((${heightNumber} * 2) * 1px); - padding: calc(${designUnit} * 1.5px) calc(${designUnit} * 2px + 1px); - } - - :host .control { - resize: none; - } - - :host(.resize-both) .control { - resize: both; - } - - :host(.resize-horizontal) .control { - resize: horizontal; - } - - :host(.resize-vertical) .control { - resize: vertical; - } - - :host([cols]) { - width: initial; - } - - :host([rows]) .control { - height: initial; - } - `.withBehaviors( - appearanceBehavior('outline', inputOutlineStyles(context, definition, logicalControlSelector)), - appearanceBehavior('filled', inputFilledStyles(context, definition, logicalControlSelector)), - forcedColorsStylesheetBehavior(inputForcedColorStyles(context, definition, logicalControlSelector)), - ); diff --git a/packages/web-components/src/text-area/text-area.vscode.definition.json b/packages/web-components/src/text-area/text-area.vscode.definition.json deleted file mode 100644 index c2078639ff816..0000000000000 --- a/packages/web-components/src/text-area/text-area.vscode.definition.json +++ /dev/null @@ -1,141 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-text-area", - "title": "Text area", - "description": "The Fluent UI text-area element", - "attributes": [ - { - "name": "appearance", - "title": "Appearance", - "description": "The text area's visual treatment", - "default": "outline", - "required": false, - "type": "string", - "values": [{ "name": "outline" }, { "name": "filled" }] - }, - { - "name": "resize", - "title": "Resize", - "description": "The resize mode of the element", - "required": false, - "type": "string", - "values": [{ "name": "none" }, { "name": "both" }, { "name": "horizontal" }, { "name": "vertical" }], - "default": "none" - }, - { - "name": "autofocus", - "title": "Autofocus", - "description": "Determines if the element should receive document focus on page load", - "required": false, - "type": "boolean", - "default": false - }, - { - "name": "cols", - "title": "Columns", - "description": "Sizes the element vertically by a number of character columns", - "required": false, - "type": "number", - "default": 20 - }, - { - "name": "form", - "description": "The form attribute", - "required": false, - "type": "string" - }, - { - "name": "list", - "title": "List ID", - "description": "Allows associating a datalist to the component", - "required": false, - "type": "string", - "default": "" - }, - { - "name": "maxlength", - "title": "Maximum length", - "description": "The maximum number of characters a user can enter", - "required": false, - "type": "number" - }, - { - "name": "minlength", - "title": "Minimum length", - "description": "The minimum number of characters a user can enter", - "required": false, - "type": "number" - }, - { - "name": "placeholder", - "title": "Placeholder", - "description": "Sets the placeholder value of the element, generally used to provide a hint to the user", - "required": false, - "type": "string" - }, - { - "name": "rows", - "title": "Rows", - "description": "Sizes the element vertically by a number of character rows", - "required": false, - "type": "number" - }, - { - "name": "spellcheck", - "title": "Spellcheck", - "description": "Controls whether or not to enable spell checking for the input field, or if the default spell checking configuration should be used", - "required": false, - "type": "boolean" - }, - { - "name": "value", - "title": "Value", - "description": "The HTML value attribute of the text area", - "required": false, - "type": "string" - }, - { - "name": "name", - "title": "Name", - "description": "This element's value will be surfaced during form submission under the provided name", - "type": "string", - "default": "", - "required": false - }, - { - "name": "required", - "title": "Required", - "description": "Require the field to be completed prior to form submission", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Sets the disabled state of the text area", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "readonly", - "title": "Readonly", - "description": "When true, the control will be immutable by user interaction", - "type": "boolean", - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the text area represents its visual label" - } - ] - } - ] -} diff --git a/packages/web-components/src/text-field/fixtures/text-field.html b/packages/web-components/src/text-field/fixtures/text-field.html deleted file mode 100644 index 20f362accb6ab..0000000000000 --- a/packages/web-components/src/text-field/fixtures/text-field.html +++ /dev/null @@ -1,109 +0,0 @@ -

Text field

-

Default

- -Label - -

Full Width

- - -

Placeholder

- - - -

Required

- - - -

Disabled

- -label - - - - - - - - -

Read only

- -label - - -

Autofocus

-autofocus - - -

With start

- - - - - - - -

With end

- - - - - - -

Filled

-
Default
- -label - -
Placeholder
- - - -
Required
- - - -
Disabled
- -label - - - - - - - - -
Read only
- -label - - -

Visual vs audio label

- - Visible label - - - -

Audio label only

- - - - - -

With aria-label

- - -
- -

In a form

- - -
diff --git a/packages/web-components/src/text-field/index.ts b/packages/web-components/src/text-field/index.ts deleted file mode 100644 index cd68fa04c6805..0000000000000 --- a/packages/web-components/src/text-field/index.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { attr } from '@microsoft/fast-element'; -import { TextField as FoundationTextField, textFieldTemplate as template } from '@microsoft/fast-foundation'; -import { textFieldStyles as styles } from './text-field.styles'; - -/** - * Text field appearances - * @public - */ -export type TextFieldAppearance = 'filled' | 'outline'; - -/** - * The Fluent text field class - * @internal - */ -export class TextField extends FoundationTextField { - /** - * The appearance of the element. - * - * @public - * @remarks - * HTML Attribute: appearance - */ - @attr - public appearance: TextFieldAppearance; - - /** - * @internal - */ - public appearanceChanged(oldValue: TextFieldAppearance, newValue: TextFieldAppearance): void { - if (oldValue !== newValue) { - this.classList.add(newValue); - this.classList.remove(oldValue); - } - } - - /** - * @internal - */ - public connectedCallback(): void { - super.connectedCallback(); - - if (!this.appearance) { - this.appearance = 'outline'; - } - } -} - -/** - * The Fluent Text Field Custom Element. Implements {@link @microsoft/fast-foundation#TextField}, - * {@link @microsoft/fast-foundation#textFieldTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - * - * {@link https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus | delegatesFocus} - */ -export const fluentTextField = TextField.compose({ - baseName: 'text-field', - baseClass: FoundationTextField, - template, - styles, - shadowOptions: { - delegatesFocus: true, - }, -}); - -/** - * Styles for TextField - * @public - */ -export const textFieldStyles = styles; diff --git a/packages/web-components/src/text-field/text-field.stories.ts b/packages/web-components/src/text-field/text-field.stories.ts deleted file mode 100644 index 8a69de3bd395b..0000000000000 --- a/packages/web-components/src/text-field/text-field.stories.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { fluentTextField } from './index'; - -export default { - title: 'Components/Text Field', - component: fluentTextField, - argTypes: { - appearance: { - options: ['filled', 'outline'], - defaultValue: 'outline', - control: { type: 'radio' }, - }, - autoFocus: { - description: 'Automatically focuses the control', - control: { type: 'boolean' }, - }, - disabled: { - description: 'The text field should be submitted with the form but should not be editable', - control: { type: 'boolean' }, - }, - list: { - control: { type: 'text' }, - }, - maxlength: { - control: { type: 'number' }, - }, - name: { - control: { type: 'text' }, - }, - minlength: { - control: { type: 'number' }, - }, - pattern: { - description: `A regular expression the input's contents must match in order to be valid`, - control: { type: 'text' }, - }, - placeholder: { - description: 'An exemplar value to display in the input field whenever it is empty', - defaultValue: 'Placeholder', - control: { type: 'text' }, - }, - readonly: { - control: { type: 'boolean' }, - }, - required: { - control: { type: 'boolean' }, - }, - spellcheck: { - control: { type: 'boolean' }, - }, - type: { - options: ['text', 'email', 'password', 'tel', 'url'], - control: { type: 'radio' }, - }, - }, -}; - -const TextFieldTemplate = ({ - appearance, - autoFocus, - disabled, - list, - maxlength, - name, - minlength, - pattern, - placeholder, - readonly, - required, - size, - spellcheck, - type, -}) => - ``; - -export const TextField = TextFieldTemplate.bind({}); - -TextField.args = { - placeholder: 'placeholder', - autoFocus: false, - disabled: false, - readonly: false, - required: false, -}; - -const example = ` - -`; - -TextField.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/text-field/text-field.styles.ts b/packages/web-components/src/text-field/text-field.styles.ts deleted file mode 100644 index 110607e7c3a4b..0000000000000 --- a/packages/web-components/src/text-field/text-field.styles.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - display, - ElementDefinitionContext, - forcedColorsStylesheetBehavior, - FoundationElementDefinition, -} from '@microsoft/fast-foundation'; -import { - baseInputStyles, - inputFilledStyles, - inputForcedColorStyles, - inputOutlineStyles, - inputStateStyles, -} from '../styles'; -import { appearanceBehavior } from '../utilities/behaviors'; -import { designUnit } from '../design-tokens'; - -const logicalControlSelector: string = '.root'; - -export const textFieldStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles = ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => - css` - ${display('inline-block')} - - ${baseInputStyles(context, definition, logicalControlSelector)} - - ${inputStateStyles(context, definition, logicalControlSelector)} - - .root { - display: flex; - flex-direction: row; - } - - .control { - -webkit-appearance: none; - color: inherit; - background: transparent; - border: 0; - height: calc(100% - 4px); - margin-top: auto; - margin-bottom: auto; - padding: 0 calc(${designUnit} * 2px + 1px); - font-family: inherit; - font-size: inherit; - line-height: inherit; - } - - .start, - .end { - display: flex; - margin: auto; - } - - .start { - display: flex; - margin-inline-start: 11px; - } - - .end { - display: flex; - margin-inline-end: 11px; - } - `.withBehaviors( - appearanceBehavior('outline', inputOutlineStyles(context, definition, logicalControlSelector)), - appearanceBehavior('filled', inputFilledStyles(context, definition, logicalControlSelector)), - forcedColorsStylesheetBehavior(inputForcedColorStyles(context, definition, logicalControlSelector)), - ); diff --git a/packages/web-components/src/text-field/text-field.vscode.definition.json b/packages/web-components/src/text-field/text-field.vscode.definition.json deleted file mode 100644 index 7ca34d545d111..0000000000000 --- a/packages/web-components/src/text-field/text-field.vscode.definition.json +++ /dev/null @@ -1,150 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-text-field", - "title": "Text field", - "description": "The Fluent UI text-field element", - "attributes": [ - { - "name": "value", - "title": "Value", - "description": "The HTML value attribute of the text field", - "required": false, - "type": "string" - }, - { - "name": "appearance", - "title": "Appearance", - "description": "The text field's visual treatment", - "default": "outline", - "values": [{ "name": "outline" }, { "name": "filled" }], - "type": "string", - "required": false - }, - { - "name": "autofocus", - "title": "Autofocus", - "description": "Determines if the element should receive document focus on page load", - "required": false, - "type": "boolean", - "default": false - }, - { - "name": "placeholder", - "title": "Placeholder", - "description": "Sets the placeholder value of the element, generally used to provide a hint to the user", - "required": false, - "type": "string" - }, - { - "name": "type", - "title": "Type", - "description": "Specifies the type of text input for the field", - "default": "text", - "values": [ - { "name": "email" }, - { "name": "password" }, - { "name": "tel" }, - { "name": "text" }, - { "name": "url" } - ], - "type": "string", - "required": false - }, - { - "name": "list", - "title": "List ID", - "description": "Allows associating a datalist to the component", - "required": false, - "type": "string", - "default": "" - }, - { - "name": "maxlength", - "title": "Maximum length", - "description": "The maximum number of characters a user can enter", - "required": false, - "type": "number" - }, - { - "name": "minlength", - "title": "Minimum length", - "description": "The minimum number of characters a user can enter", - "required": false, - "type": "number" - }, - { - "name": "pattern", - "title": "Validation pattern", - "description": "A regular expression that the value must match to pass validation", - "required": false, - "type": "string" - }, - { - "name": "size", - "title": "Size", - "description": "Sets the width of the element to a specified number of characters", - "required": false, - "type": "number" - }, - { - "name": "spellcheck", - "title": "Spellcheck", - "description": "Controls whether or not to enable spell checking for the input field, or if the default spell checking configuration should be used", - "required": false, - "type": "boolean" - }, - { - "name": "name", - "title": "Name", - "description": "This element's value will be surfaced during form submission under the provided name", - "type": "string", - "default": "", - "required": false - }, - { - "name": "required", - "title": "Required", - "description": "Require the field to be completed prior to form submission", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Sets the disabled state of the number field", - "type": "boolean", - "default": false, - "required": false - }, - { - "name": "readonly", - "title": "Readonly", - "description": "When true, the control will be immutable by user interaction", - "type": "boolean", - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The content of the radio represents its visual label" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned before the option content" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the option content" - } - ] - } - ] -} diff --git a/packages/web-components/src/toolbar/fixtures/toolbar.html b/packages/web-components/src/toolbar/fixtures/toolbar.html deleted file mode 100644 index 1e8ee3373b210..0000000000000 --- a/packages/web-components/src/toolbar/fixtures/toolbar.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - - - - - - - -

Toolbar

- -

Default

- - - - - - - - - - -

Fluent components

- - Accent Button - Stealth Button - - One - Two - Three - - - Please Please Me - With The Beatles - A Hard Day's Night - Beatles for Sale - Help! - Rubber Soul - Revolver - Sgt. Pepper's Lonely Hearts Club Band - Magical Mystery Tour - The Beatles - Yellow Submarine - Abbey Road - Let It Be - - Button - - Option 1 - Second option - Option 3 - - Checkbox - - - - Add - Open - Copy - Export - Automate - - Stealth - Refresh - 21 items - - Filter - - - - - - -

Dark Mode

- - - - Add - Open - Copy - Export - Automate - - Stealth - Refresh - 21 items - - Filter - - - - - - - -

Slotted End Items w/ Min Width

- - - - - Add - Open - Copy - - Refresh - 21 items - - Filter - - - - - - - - - - -

Toolbar with slotted span label

- - Span Label - - - - - -

Toolbar with external label

- - - - - - - -

Toolbar with invisible label

- - - - - - -

Vertical orientation

- - Span Label - - - - - -

Disabled Elements

- - One - Two - Three - - - - One - Two - Three - - - - One - Two - Three - - - - One - Two - Three - - - - One - Two - Three - - - - Span Label - One - Two - Three - - - - One - Two - Three - - -

RTL Mode

- - One - Two - Three - - - - One - Two - Three - - -

Start/End Slots

- - - - - - - - - - - - - - - - - diff --git a/packages/web-components/src/toolbar/index.ts b/packages/web-components/src/toolbar/index.ts deleted file mode 100644 index 97949a8e0561a..0000000000000 --- a/packages/web-components/src/toolbar/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Toolbar as FoundationToolbar, toolbarTemplate as template } from '@microsoft/fast-foundation'; -import { toolbarStyles as styles } from './toolbar.styles'; - -/** - * The Fluent toolbar class - * @internal - */ -export class Toolbar extends FoundationToolbar {} - -/** - * The Fluent Toolbar Custom Element. Implements {@link @microsoft/fast-foundation#Toolbar}, - * {@link @microsoft/fast-foundation#toolbarTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentToolbar = Toolbar.compose({ - baseName: 'toolbar', - baseClass: FoundationToolbar, - template, - styles, -}); diff --git a/packages/web-components/src/toolbar/toolbar.stories.ts b/packages/web-components/src/toolbar/toolbar.stories.ts deleted file mode 100644 index bfdb387f7b442..0000000000000 --- a/packages/web-components/src/toolbar/toolbar.stories.ts +++ /dev/null @@ -1,11 +0,0 @@ -import './index'; -import '../button'; -import '../select'; -import '../badge'; -import ToolbarTemplate from './fixtures/toolbar.html'; - -export default { - title: 'Components/Toolbar', -}; - -export const Toolbar = () => ToolbarTemplate; diff --git a/packages/web-components/src/toolbar/toolbar.styles.ts b/packages/web-components/src/toolbar/toolbar.styles.ts deleted file mode 100644 index 75c1ebac76f31..0000000000000 --- a/packages/web-components/src/toolbar/toolbar.styles.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - display, - ElementDefinitionContext, - focusVisible, - forcedColorsStylesheetBehavior, - FoundationElementDefinition, -} from '@microsoft/fast-foundation'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { designUnit, fillColor } from '../design-tokens'; -import { focusTreatmentBase } from '../styles/focus'; - -export const toolbarStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - ${display('inline-flex')} :host { - --toolbar-item-gap: calc(${designUnit} * 1px); - background: ${fillColor}; - fill: currentcolor; - padding: var(--toolbar-item-gap); - box-sizing: border-box; - align-items: center; - } - - :host(${focusVisible}) { - ${focusTreatmentBase} - } - - .positioning-region { - align-items: center; - display: inline-flex; - flex-flow: row wrap; - justify-content: flex-start; - flex-grow: 1; - } - - :host([orientation='vertical']) .positioning-region { - flex-direction: column; - align-items: start; - } - - ::slotted(:not([slot])) { - flex: 0 0 auto; - margin: 0 var(--toolbar-item-gap); - } - - :host([orientation='vertical']) ::slotted(:not([slot])) { - margin: var(--toolbar-item-gap) 0; - } - - :host([orientation='vertical']) { - display: inline-flex; - flex-direction: column; - } - - .start, - .end { - display: flex; - align-items: center; - } - - .end { - margin-inline-start: auto; - } - - .start__hidden, - .end__hidden { - display: none; - } - - ::slotted(svg) { - ${/* Glyph size is temporary - replace when adaptive typography is figured out */ ''} - width: 16px; - height: 16px; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host(:${focusVisible}) { - outline-color: ${SystemColors.Highlight}; - color: ${SystemColors.ButtonText}; - forced-color-adjust: none; - } - `, - ), - ); diff --git a/packages/web-components/src/toolbar/toolbar.vscode.definition.json b/packages/web-components/src/toolbar/toolbar.vscode.definition.json deleted file mode 100644 index 9e5fb991e3be3..0000000000000 --- a/packages/web-components/src/toolbar/toolbar.vscode.definition.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-toolbar", - "title": "Toolbar", - "description": "The Fluent toolbar element", - "attributes": [ - { - "name": "orientation", - "title": "Orientation", - "description": "The orientation of the toolbar", - "default": "horizontal", - "values": [{ "name": "horizontal" }, { "name": "vertical" }], - "required": false, - "type": "string" - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The toolbar content" - }, - { - "name": "label", - "title": "Label slot", - "description": "The visual label for the toolbar" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned before the contents of the toolbar" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the contents of the toolbar" - } - ] - } - ] -} diff --git a/packages/web-components/src/tooltip/fixtures/tooltip.html b/packages/web-components/src/tooltip/fixtures/tooltip.html deleted file mode 100644 index d332248ed5b5c..0000000000000 --- a/packages/web-components/src/tooltip/fixtures/tooltip.html +++ /dev/null @@ -1,115 +0,0 @@ -

Tooltip

- -

Default

-
- Helpful text is helpful - anchor -
- -

Show/Hide

-
- Always visible - Always visible - Always visible - Always visible - Toggle tooltips -
- -

Top

-
- Helpful text is helpful - - anchor -
- -

Right

-
- Helpful text is helpful - - anchor -
- -

Bottom

-
- Helpful text is helpful - - anchor -
- -

Left

-
- Helpful text is helpful - - anchor -
- -

in a flex container

-
-
-
- anchor -
-
- Helpful text is helpful - Helpful text is helpful - Helpful text is helpful - Helpful text is helpful -
- -

Switch anchors

-
- Helpful text is helpful - - anchor - - anchor - - anchor - - anchor - - anchor - - anchor - - anchor - - anchor -
- -

RTL

-
- anchor - - Left - - Right -
- -

start/end

-
- anchor - - Start - - End -
- -

start/end RTL

-
- anchor - - Start - - End -
diff --git a/packages/web-components/src/tooltip/index.ts b/packages/web-components/src/tooltip/index.ts deleted file mode 100644 index 29261bed85ce5..0000000000000 --- a/packages/web-components/src/tooltip/index.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Tooltip as FoundationTooltip, tooltipTemplate as template } from '@microsoft/fast-foundation'; -import { fillColor, neutralLayerFloating } from '../design-tokens'; -import { tooltipStyles as styles } from './tooltip.styles'; - -/** - * The Fluent tooltip class - * @internal - */ -export class Tooltip extends FoundationTooltip { - /** - * @internal - */ - public connectedCallback(): void { - super.connectedCallback(); - - fillColor.setValueFor(this, neutralLayerFloating); - } -} - -/** - * The Fluent Tooltip Custom Element. Implements {@link @microsoft/fast-foundation#Tooltip}, - * {@link @microsoft/fast-foundation#tooltipTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const fluentTooltip = Tooltip.compose({ - baseName: 'tooltip', - baseClass: FoundationTooltip, - template, - styles, -}); diff --git a/packages/web-components/src/tooltip/tooltip.stories.ts b/packages/web-components/src/tooltip/tooltip.stories.ts deleted file mode 100644 index 82dc2102f09e5..0000000000000 --- a/packages/web-components/src/tooltip/tooltip.stories.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { fluentTooltip } from './index'; - -export default { - title: 'Components/Tooltip', - components: fluentTooltip, - argTypes: { - position: { - options: ['top', 'right', 'bottom', 'left'], - control: { type: 'radio' }, - }, - }, -}; - -const TooltipTemplate = ({ label, position }) => ` - - ${label} - - Reveal Tooltip -`; - -export const Tooltip = TooltipTemplate.bind({}); - -Tooltip.args = { - label: `I'm helping!`, -}; - -const example = ` - Helpful text is helpful -`; - -Tooltip.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/tooltip/tooltip.styles.ts b/packages/web-components/src/tooltip/tooltip.styles.ts deleted file mode 100644 index b3d070674d300..0000000000000 --- a/packages/web-components/src/tooltip/tooltip.styles.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { - AnchoredRegion, - ElementDefinitionContext, - forcedColorsStylesheetBehavior, - FoundationElementDefinition -} from '@microsoft/fast-foundation'; -import { elevationShadowTooltip } from '../styles/index'; -import { - controlCornerRadius, - fillColor, - neutralForegroundRest, - neutralStrokeLayerRest, - strokeWidth, -} from '../design-tokens'; -import { typeRampBase } from '../styles/patterns/type-ramp'; - -export const tooltipStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => - css` - :host { - position: relative; - contain: layout; - overflow: visible; - height: 0; - width: 0; - z-index: 10000; - } - - .tooltip { - box-sizing: border-box; - border-radius: calc(${controlCornerRadius} * 1px); - border: calc(${strokeWidth} * 1px) solid ${neutralStrokeLayerRest}; - background: ${fillColor}; - color: ${neutralForegroundRest}; - padding: 4px 12px; - height: fit-content; - width: fit-content; - ${typeRampBase} - white-space: nowrap; - box-shadow: ${elevationShadowTooltip}; - } - - ${context.tagFor(AnchoredRegion)} { - display: flex; - justify-content: center; - align-items: center; - overflow: visible; - flex-direction: row; - } - - ${context.tagFor(AnchoredRegion)}.right, - ${context.tagFor(AnchoredRegion)}.left { - flex-direction: column; - } - - ${context.tagFor(AnchoredRegion)}.top .tooltip::after, - ${context.tagFor(AnchoredRegion)}.bottom .tooltip::after, - ${context.tagFor(AnchoredRegion)}.left .tooltip::after, - ${context.tagFor(AnchoredRegion)}.right .tooltip::after { - content: ''; - width: 12px; - height: 12px; - background: ${fillColor}; - border-top: calc(${strokeWidth} * 1px) solid ${neutralStrokeLayerRest}; - border-left: calc(${strokeWidth} * 1px) solid ${neutralStrokeLayerRest}; - position: absolute; - } - - ${context.tagFor(AnchoredRegion)}.top .tooltip::after { - transform: translateX(-50%) rotate(225deg); - bottom: 5px; - left: 50%; - } - - ${context.tagFor(AnchoredRegion)}.top .tooltip { - margin-bottom: 12px; - } - - ${context.tagFor(AnchoredRegion)}.bottom .tooltip::after { - transform: translateX(-50%) rotate(45deg); - top: 5px; - left: 50%; - } - - ${context.tagFor(AnchoredRegion)}.bottom .tooltip { - margin-top: 12px; - } - - ${context.tagFor(AnchoredRegion)}.left .tooltip::after { - transform: translateY(-50%) rotate(135deg); - top: 50%; - right: 5px; - } - - ${context.tagFor(AnchoredRegion)}.left .tooltip { - margin-right: 12px; - } - - ${context.tagFor(AnchoredRegion)}.right .tooltip::after { - transform: translateY(-50%) rotate(-45deg); - top: 50%; - left: 5px; - } - - ${context.tagFor(AnchoredRegion)}.right .tooltip { - margin-left: 12px; - } - `.withBehaviors( - forcedColorsStylesheetBehavior( - css` - :host([disabled]) { - opacity: 1; - } - ${context.tagFor(AnchoredRegion)}.top .tooltip::after, - ${context.tagFor(AnchoredRegion)}.bottom .tooltip::after, - ${context.tagFor(AnchoredRegion)}.left .tooltip::after, - ${context.tagFor(AnchoredRegion)}.right .tooltip::after { - content: ''; - width: unset; - height: unset; - } - `, - ), - ); diff --git a/packages/web-components/src/tooltip/tooltip.vscode.definition.json b/packages/web-components/src/tooltip/tooltip.vscode.definition.json deleted file mode 100644 index eff0e849349ca..0000000000000 --- a/packages/web-components/src/tooltip/tooltip.vscode.definition.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-tooltip", - "title": "Tooltip", - "description": "The Fluent UI tooltip element", - "attributes": [ - { - "name": "visible", - "title": "Visible", - "description": "Sets whether the tooltip is visible or not", - "type": "boolean", - "required": false - }, - { - "name": "anchor", - "title": "Anchor ID", - "description": "The HTML ID of the element the tooltip is positioned relative to", - "type": "string", - "required": false - }, - { - "name": "delay", - "title": "Delay", - "description": "The delay in milliseconds before a tooltip is shown after a hover event", - "type": "number", - "default": 300, - "required": false - }, - { - "name": "position", - "title": "Position", - "description": "Controls the placement of the tooltip relative to the configured 'Anchor ID'", - "values": [ - { "name": "top" }, - { "name": "right" }, - { "name": "bottom" }, - { "name": "left" }, - { "name": "start" }, - { "name": "end" } - ], - "type": "string", - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The tooltip content" - } - ] - } - ] -} diff --git a/packages/web-components/src/tree-item/fixtures/tree-item.html b/packages/web-components/src/tree-item/fixtures/tree-item.html deleted file mode 100644 index 8f73377505c19..0000000000000 --- a/packages/web-components/src/tree-item/fixtures/tree-item.html +++ /dev/null @@ -1,68 +0,0 @@ -

Tree item

-

Default

-Tree item - -

Nested

- - Tree item - Nested tree item - - -

Selected

-Tree item - -

Selected and disabled

-Tree item - -

Before content

- - - - - Tree item - -
- - - - - Tree item - - -

After content

- - Tree item - - - - -
- - Tree item - - - - - -

Disabled

- - - - - Tree item disabled - - - - diff --git a/packages/web-components/src/tree-item/index.ts b/packages/web-components/src/tree-item/index.ts deleted file mode 100644 index 1d9e05954ef6a..0000000000000 --- a/packages/web-components/src/tree-item/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { treeItemTemplate as template, TreeItem, TreeItemOptions } from '@microsoft/fast-foundation'; -import { treeItemStyles as styles } from './tree-item.styles'; - -/** - * The Fluent tree item Custom Element. Implements, {@link @microsoft/fast-foundation#TreeItem} - * {@link @microsoft/fast-foundation#treeItemTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - * - */ -export const fluentTreeItem = TreeItem.compose({ - baseName: 'tree-item', - template, - styles, - expandCollapseGlyph: ` - - - - `, -}); - -/** - * Styles for TreeItem - * @public - */ -export const treeItemStyles = styles; - -/** - * Tree item base class - * @public - */ -export { TreeItem }; diff --git a/packages/web-components/src/tree-item/tree-item.stories.ts b/packages/web-components/src/tree-item/tree-item.stories.ts deleted file mode 100644 index fbe5b8efa50d2..0000000000000 --- a/packages/web-components/src/tree-item/tree-item.stories.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { fluentTreeItem } from './index'; - -export default { - title: 'Components/Tree Item', - component: fluentTreeItem, - argTypes: { - disabled: { - control: { type: 'boolean' }, - }, - selected: { - control: { type: 'boolean' }, - }, - }, -}; - -const TreeItemTemplate = ({ disabled, label, selected }) => ` - ${label}`; - -export const TreeItem = TreeItemTemplate.bind({}); - -TreeItem.args = { - label: 'Tree Item', - disabled: false, - selected: false, -}; - -const example = ` -Tree item -`; - -TreeItem.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/tree-item/tree-item.styles.ts b/packages/web-components/src/tree-item/tree-item.styles.ts deleted file mode 100644 index 28a6efc4dd63d..0000000000000 --- a/packages/web-components/src/tree-item/tree-item.styles.ts +++ /dev/null @@ -1,277 +0,0 @@ -import { css, cssPartial, ElementStyles } from '@microsoft/fast-element'; -import { - DesignToken, - disabledCursor, - display, - ElementDefinitionContext, - focusVisible, - forcedColorsStylesheetBehavior, - TreeItemOptions, -} from '@microsoft/fast-foundation'; -import { SystemColors } from '@microsoft/fast-web-utilities'; -import { DirectionalStyleSheetBehavior, heightNumber } from '../styles/index'; -import { - accentFillRest, - baseHeightMultiplier, - bodyFont, - controlCornerRadius, - density, - designUnit, - disabledOpacity, - focusStrokeWidth, - neutralFillSecondaryRecipe, - neutralFillSecondaryRest, - neutralFillStealthActive, - neutralFillStealthHover, - neutralFillStealthRecipe, - neutralFillStealthRest, - neutralForegroundRest, - strokeWidth, -} from '../design-tokens'; -import { Swatch } from '../color/swatch'; -import { typeRampBase } from '../styles/patterns/type-ramp'; -import { focusTreatmentBase } from '../styles/focus'; - -const ltr = css` - .expand-collapse-button svg { - transform: rotate(0deg); - } - :host(.nested) .expand-collapse-button { - left: var(--expand-collapse-button-nested-width, calc(${heightNumber} * -1px)); - } - :host([selected])::after { - left: calc(${focusStrokeWidth} * 1px); - } - :host([expanded]) > .positioning-region .expand-collapse-button svg { - transform: rotate(90deg); - } -`; - -const rtl = css` - .expand-collapse-button svg { - transform: rotate(180deg); - } - :host(.nested) .expand-collapse-button { - right: var(--expand-collapse-button-nested-width, calc(${heightNumber} * -1px)); - } - :host([selected])::after { - right: calc(${focusStrokeWidth} * 1px); - } - :host([expanded]) > .positioning-region .expand-collapse-button svg { - transform: rotate(90deg); - } -`; - -export const expandCollapseButtonSize = cssPartial`((${baseHeightMultiplier} / 2) * ${designUnit}) + ((${designUnit} * ${density}) / 2)`; - -const expandCollapseHover = DesignToken.create('tree-item-expand-collapse-hover').withDefault( - (target: HTMLElement) => { - const recipe = neutralFillStealthRecipe.getValueFor(target); - return recipe.evaluate(target, recipe.evaluate(target).hover).hover; - }, -); - -const selectedExpandCollapseHover = DesignToken.create('tree-item-expand-collapse-selected-hover').withDefault( - (target: HTMLElement) => { - const baseRecipe = neutralFillSecondaryRecipe.getValueFor(target); - const buttonRecipe = neutralFillStealthRecipe.getValueFor(target); - return buttonRecipe.evaluate(target, baseRecipe.evaluate(target).rest).hover; - }, -); - -export const treeItemStyles: (context: ElementDefinitionContext, definition: TreeItemOptions) => ElementStyles = ( - context: ElementDefinitionContext, - definition: TreeItemOptions, -) => - css` - ${display('block')} :host { - contain: content; - position: relative; - outline: none; - color: ${neutralForegroundRest}; - fill: currentcolor; - cursor: pointer; - font-family: ${bodyFont}; - --expand-collapse-button-size: calc(${heightNumber} * 1px); - --tree-item-nested-width: 0; - } - - .positioning-region { - display: flex; - position: relative; - box-sizing: border-box; - background: ${neutralFillStealthRest}; - border: calc(${strokeWidth} * 1px) solid transparent; - border-radius: calc(${controlCornerRadius} * 1px); - height: calc((${heightNumber} + 1) * 1px); - } - - :host(:${focusVisible}) .positioning-region { - ${focusTreatmentBase} - } - - .positioning-region::before { - content: ''; - display: block; - width: var(--tree-item-nested-width); - flex-shrink: 0; - } - - :host(:not([disabled])) .positioning-region:hover { - background: ${neutralFillStealthHover}; - } - - :host(:not([disabled])) .positioning-region:active { - background: ${neutralFillStealthActive}; - } - - .content-region { - display: inline-flex; - align-items: center; - white-space: nowrap; - width: 100%; - height: calc(${heightNumber} * 1px); - margin-inline-start: calc(${designUnit} * 2px + 8px); - ${typeRampBase} - } - - .items { - display: none; - ${ - /* Font size should be based off calc(1em + (design-unit + glyph-size-number) * 1px) - - update when density story is figured out */ '' - } font-size: calc(1em + (${designUnit} + 16) * 1px); - } - - .expand-collapse-button { - background: none; - border: none; - border-radius: calc(${controlCornerRadius} * 1px); - ${ - /* Width and Height should be based off calc(glyph-size-number + (design-unit * 4) * 1px) - - update when density story is figured out */ '' - } width: calc((${expandCollapseButtonSize} + (${designUnit} * 2)) * 1px); - height: calc((${expandCollapseButtonSize} + (${designUnit} * 2)) * 1px); - padding: 0; - display: flex; - justify-content: center; - align-items: center; - cursor: pointer; - margin: 0 6px; - } - - .expand-collapse-button svg { - transition: transform 0.1s linear; - pointer-events: none; - } - - .start, - .end { - display: flex; - } - - .start { - ${ - /* need to swap out once we understand how horizontalSpacing will work */ '' - } margin-inline-end: calc(${designUnit} * 2px + 2px); - } - - .end { - ${ - /* need to swap out once we understand how horizontalSpacing will work */ '' - } margin-inline-start: calc(${designUnit} * 2px + 2px); - } - - :host(.expanded) > .items { - display: block; - } - - :host([disabled]) { - opacity: ${disabledOpacity}; - cursor: ${disabledCursor}; - } - - :host(.nested) .content-region { - position: relative; - margin-inline-start: var(--expand-collapse-button-size); - } - - :host(.nested) .expand-collapse-button { - position: absolute; - } - - :host(.nested) .expand-collapse-button:hover { - background: ${expandCollapseHover}; - } - - :host(:not([disabled])[selected]) .positioning-region { - background: ${neutralFillSecondaryRest}; - } - - :host(:not([disabled])[selected]) .expand-collapse-button:hover { - background: ${selectedExpandCollapseHover}; - } - - :host([selected])::after { - content: ''; - display: block; - position: absolute; - top: calc((${heightNumber} / 4) * 1px); - width: 3px; - height: calc((${heightNumber} / 2) * 1px); - ${ - /* The french fry background needs to be calculated based on the selected background state for this control. - We currently have no way of changing that, so setting to accent-foreground-rest for the time being */ '' - } background: ${accentFillRest}; - border-radius: calc(${controlCornerRadius} * 1px); - } - - ::slotted(fluent-tree-item) { - --tree-item-nested-width: 1em; - --expand-collapse-button-nested-width: calc(${heightNumber} * -1px); - } - `.withBehaviors( - new DirectionalStyleSheetBehavior(ltr, rtl), - forcedColorsStylesheetBehavior( - css` - :host { - color: ${SystemColors.ButtonText}; - } - .positioning-region { - border-color: ${SystemColors.ButtonFace}; - background: ${SystemColors.ButtonFace}; - } - :host(:not([disabled])) .positioning-region:hover, - :host(:not([disabled])) .positioning-region:active, - :host(:not([disabled])[selected]) .positioning-region { - background: ${SystemColors.Highlight}; - } - :host .positioning-region:hover .content-region, - :host([selected]) .positioning-region .content-region { - forced-color-adjust: none; - color: ${SystemColors.HighlightText}; - } - :host([disabled][selected]) .positioning-region .content-region { - color: ${SystemColors.GrayText}; - } - :host([selected])::after { - background: ${SystemColors.HighlightText}; - } - :host(:${focusVisible}) .positioning-region { - forced-color-adjust: none; - outline-color: ${SystemColors.ButtonFace}; - } - :host([disabled]), - :host([disabled]) .content-region, - :host([disabled]) .positioning-region:hover .content-region { - opacity: 1; - color: ${SystemColors.GrayText}; - } - :host(.nested) .expand-collapse-button:hover, - :host(:not([disabled])[selected]) .expand-collapse-button:hover { - background: ${SystemColors.ButtonFace}; - fill: ${SystemColors.ButtonText}; - } - `, - ), - ); diff --git a/packages/web-components/src/tree-item/tree-item.vscode.definition.json b/packages/web-components/src/tree-item/tree-item.vscode.definition.json deleted file mode 100644 index 0a7ea398cc658..0000000000000 --- a/packages/web-components/src/tree-item/tree-item.vscode.definition.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-tree-item", - "title": "Tree item", - "description": "The Fluent UI tree item element", - "attributes": [ - { - "name": "expanded", - "title": "Expanded", - "description": "Whether tree item is expanded or not", - "default": false, - "required": false, - "type": "boolean" - }, - { - "name": "selected", - "title": "Selected", - "description": "Whether tree item is selected or not", - "default": false, - "required": false, - "type": "boolean" - }, - { - "name": "disabled", - "title": "Disabled", - "description": "Sets the disabled state of the tree item", - "type": "boolean", - "default": false, - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "The visual label of the tree item" - }, - { - "name": "item", - "title": "Item slot", - "description": "Nested fluent-tree-item elements automatically apply a slot of item for an intuitive API" - }, - { - "name": "expand-collapse-glyph", - "title": "Expand collapse glyph slot", - "description": "Slot to provide a custom visual to represent the expanded and collapsed states" - }, - { - "name": "start", - "title": "Start slot", - "description": "Contents of the start slot are positioned after the expand/collapse glyph and before the item content" - }, - { - "name": "end", - "title": "End slot", - "description": "Contents of the end slot are positioned after the item content" - } - ] - } - ] -} diff --git a/packages/web-components/src/tree-view/fixtures/tree-view.html b/packages/web-components/src/tree-view/fixtures/tree-view.html deleted file mode 100644 index ded46bfdabd44..0000000000000 --- a/packages/web-components/src/tree-view/fixtures/tree-view.html +++ /dev/null @@ -1,128 +0,0 @@ -

Tree View

-

With items (don't render collapsed nodes)

- - - Root item 1 - - Flowers - Daisy - Sunflower - Rose - - Nested item 2 - Nested item 3 - - - Root item 2 - - - Flowers - Daisy - Sunflower - Rose - - Nested item 2 - Nested item 3 - - Root item 3 - Leaf Erikson - - -

Flat tree

- - Daisy - Sunflower - Rose - - Petunia - Tulip - - -

Some expanded

- - - Root item - - Flowers - Daisy - Sunflower - Rose - - - Planes - Tomcat - Hawker Harrier - Cesna - - - - -

Pre-selected tree item

- - - Root item - - Flowers - Daisy - Sunflower - Rose - - - Planes - Tomcat - Hawker Harrier - Cesna - - - - -

With several nested items (expanded)

- - - Root item - - - - - Nested Root item 1 - - - - - - - - Nested item 4 - - - - - - Nested item 5 - - - - Nested item 2 - - - - - - Nested item 3 - - - - - - diff --git a/packages/web-components/src/tree-view/index.ts b/packages/web-components/src/tree-view/index.ts deleted file mode 100644 index 3c445c472899c..0000000000000 --- a/packages/web-components/src/tree-view/index.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { treeViewTemplate as template, TreeView } from '@microsoft/fast-foundation'; -import { treeViewStyles as styles } from './tree-view.styles'; - -/** - * The Fluent tree view Custom Element. Implements, {@link @microsoft/fast-foundation#TreeView} - * {@link @microsoft/fast-foundation#treeViewTemplate} - * - * - * @public - * @remarks - * HTML Element: \ - * - */ -export const fluentTreeView = TreeView.compose({ - baseName: 'tree-view', - template, - styles, -}); - -/** - * Styles for TreeView - * @public - */ -export const treeViewStyles = styles; - -/** - * Tree View base class - * @public - */ -export { TreeView }; diff --git a/packages/web-components/src/tree-view/tree-view.stories.ts b/packages/web-components/src/tree-view/tree-view.stories.ts deleted file mode 100644 index 04461a1c3f861..0000000000000 --- a/packages/web-components/src/tree-view/tree-view.stories.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { fluentTreeView } from './index'; - -export default { - title: 'Components/Tree View', - component: fluentTreeView, - argTypes: { - renderCollapsedNodes: { - control: { type: 'boolean' }, - }, - }, -}; - -const TreeViewTemplate = ({ renderCollapsedNodes }) => ` - - - - Root item 1 - - Root item 1 - - Flowers - Daisy - - Sunflower - - - - - - - - Rose - - Nested item 2 - Nested item 3 - - Nested item 2 - Nested item 3 - - - Root item 2 - - - Flowers - Daisy - Sunflower - Rose - - Nested item 2 - Nested item 3 - - Root item 3 - Leaf Erikson -`; - -export const TreeView = TreeViewTemplate.bind({}); - -TreeView.args = { - renderCollapsedNodes: false, -}; - -const example = ` - - - Root item 1 - - Flowers - Daisy - Sunflower - Rose - - Nested item 2 - Nested item 3 - - - Root item 2 - - - Flowers - Daisy - Sunflower - Rose - - Nested item 2 - Nested item 3 - - Root item 3 - Leaf Erikson -`; - -TreeView.parameters = { - docs: { - source: { - code: example, - }, - }, -}; diff --git a/packages/web-components/src/tree-view/tree-view.styles.ts b/packages/web-components/src/tree-view/tree-view.styles.ts deleted file mode 100644 index 84ddd37d2b77c..0000000000000 --- a/packages/web-components/src/tree-view/tree-view.styles.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { css, ElementStyles } from '@microsoft/fast-element'; -import { display, ElementDefinitionContext, FoundationElementDefinition } from '@microsoft/fast-foundation'; - -export const treeViewStyles: ( - context: ElementDefinitionContext, - definition: FoundationElementDefinition, -) => ElementStyles = (context: ElementDefinitionContext, definition: FoundationElementDefinition) => css` - :host([hidden]) { - display: none; - } - - ${display('flex')} :host { - flex-direction: column; - align-items: stretch; - min-width: fit-content; - font-size: 0; - } -`; diff --git a/packages/web-components/src/tree-view/tree-view.vscode.definition.json b/packages/web-components/src/tree-view/tree-view.vscode.definition.json deleted file mode 100644 index 01c476b267a4c..0000000000000 --- a/packages/web-components/src/tree-view/tree-view.vscode.definition.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "version": 1.1, - "tags": [ - { - "name": "fluent-tree-view", - "title": "Tree view", - "description": "The Fluent UI tree view element", - "attributes": [ - { - "name": "render-collapsed-nodes", - "title": "Render collapsed nodes", - "description": "Determines whether the tree should render nodes under collapsed items", - "type": "boolean", - "required": false - } - ], - "slots": [ - { - "name": "", - "title": "Default slot", - "description": "Supports fluent-tree-item elements or elements with a role of 'treeitem'" - } - ] - } - ] -} diff --git a/packages/web-components/src/utilities/behaviors.ts b/packages/web-components/src/utilities/behaviors.ts deleted file mode 100644 index 9b6d088008a20..0000000000000 --- a/packages/web-components/src/utilities/behaviors.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ElementStyles } from '@microsoft/fast-element'; -import { PropertyStyleSheetBehavior } from '@microsoft/fast-foundation'; - -/** - * Behavior that will conditionally apply a stylesheet based on the elements - * appearance property - * - * @param value - The value of the appearance property - * @param styles - The styles to be applied when condition matches - * - * @public - */ -export function appearanceBehavior(value: string, styles: ElementStyles) { - return new PropertyStyleSheetBehavior('appearance', value, styles); -} diff --git a/packages/web-components/src/utilities/type-ramp.ts b/packages/web-components/src/utilities/type-ramp.ts deleted file mode 100644 index a730e33f765b1..0000000000000 --- a/packages/web-components/src/utilities/type-ramp.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** @public */ -export const StandardFontWeight = { - Thin: 100, - ExtraLight: 200, - Light: 300, - Normal: 400, - Medium: 500, - SemiBold: 600, - Bold: 700, - ExtraBold: 800, - Black: 900, -} as const; From e6fe59289bcc7117f403ec7b0ab8a8085f47d4f0 Mon Sep 17 00:00:00 2001 From: Martin Hochel Date: Fri, 2 Dec 2022 10:16:30 +0100 Subject: [PATCH 004/203] ci: setup wc v3 daily releases (#25808) * ci: setup wc v3 daily releases * chore: UNDO - remove web-components from stress-test deps * ci: add change files check so we dont accidentaly release something beside wc-3 * chore: remove changefiles from master that could trigger unwanted releases * generate changefiles --- .github/workflows/check-packages.yml | 3 +- azure-pipelines.release.web-components.yml | 84 ++++++++++++++ ...-06a3ebaf-3485-4ea9-a024-ff17305e1f88.json | 7 ++ package.json | 4 +- packages/web-components/package.json | 10 +- scripts/beachball/check-wc-3-changefiles.js | 65 +++++++++++ .../beachball/check-wc-3-changefiles.spec.ts | 104 ++++++++++++++++++ scripts/beachball/config.test.ts | 16 +++ .../release-web-components.config.js | 21 ++++ scripts/beachball/utils.ts | 11 +- 10 files changed, 320 insertions(+), 5 deletions(-) create mode 100644 azure-pipelines.release.web-components.yml create mode 100644 change/@fluentui-web-components-06a3ebaf-3485-4ea9-a024-ff17305e1f88.json create mode 100644 scripts/beachball/check-wc-3-changefiles.js create mode 100644 scripts/beachball/check-wc-3-changefiles.spec.ts create mode 100644 scripts/beachball/release-web-components.config.js diff --git a/.github/workflows/check-packages.yml b/.github/workflows/check-packages.yml index cbfb7971cd1da..5d1f822240a0c 100644 --- a/.github/workflows/check-packages.yml +++ b/.github/workflows/check-packages.yml @@ -85,4 +85,5 @@ jobs: core.exportVariable('BEACHBALL_VERSION', beachballVersion); - run: | - npx beachball@$BEACHBALL_VERSION check + npx beachball@$BEACHBALL_VERSION check -b web-components-v3 + node ./scripts/beachball/check-wc-3-changefiles diff --git a/azure-pipelines.release.web-components.yml b/azure-pipelines.release.web-components.yml new file mode 100644 index 0000000000000..855074ffa1c5f --- /dev/null +++ b/azure-pipelines.release.web-components.yml @@ -0,0 +1,84 @@ +pr: none +trigger: none + +# Customize build number to include major version +# Example: web-components_20201022.1 +name: 'web-components_$(Date:yyyyMMdd)$(Rev:.r)' + +variables: + - group: 'Github and NPM secrets' + - template: .devops/templates/variables.yml + parameters: + skipComponentGovernanceDetection: false + - name: release.web_components # Used to scope beachball to release only vnext packages + value: true + - group: InfoSec-SecurityResults + - name: tags + value: production,externalfacing + +schedules: + # Triggers the nightly release + # minute 0, hour 4 in UTC (5am in UTC+1), any day of month, any month, days 1-5 of week (M-F) + # https://docs.microsoft.com/en-us/azure/devops/pipelines/build/triggers?tabs=yaml&view=azure-devops#supported-cron-syntax + - cron: '0 4 * * 1-5' + displayName: 'Daily release (M-F at 5am UTC+1)' + branches: + include: + - web-components-v3 + +jobs: + - template: .devops/templates/compliance-job.yml + + - job: Release + dependsOn: Compliance + pool: '1ES-Host-Ubuntu' + workspace: + clean: all + steps: + - template: .devops/templates/tools.yml + + - script: | + git config user.name "Fluent UI Build" + git config user.email "fluentui-internal@service.microsoft.com" + displayName: Configure git user (used by beachball) + + - task: Bash@3 + inputs: + filePath: yarn-ci.sh + displayName: yarn + + # --only makes it only run tests (otherwise due to the missing --production arg, lage would re-run the build) + # https://github.com/microsoft/fluentui/issues/21686 + - script: | + yarn lage format:check lint test build --to @fluentui/web-components + displayName: Build, Test, Lint + + - script: | + yarn beachball publish -b origin/web-components-v3 --access public -y -n $(npmToken) --config scripts/beachball/release-web-components.config.js + git reset --hard origin/web-components-v3 + env: + GITHUB_PAT: $(githubPAT) + displayName: Publish changes and bump versions + + - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: 📒 Generate Manifest + inputs: + BuildDropPath: $(System.DefaultWorkingDirectory) + + - task: PublishPipelineArtifact@1 + displayName: 📒 Publish Manifest + inputs: + artifactName: SBom-$(System.JobAttempt) + targetPath: $(System.DefaultWorkingDirectory)/_manifest + + - task: ComponentGovernanceComponentDetection@0 + displayName: 'Component governance detection' + inputs: + sourceScanPath: $(Agent.BuildDirectory) + condition: succeeded() + timeoutInMinutes: 5 + continueOnError: true + + - template: .devops/templates/cleanup.yml + parameters: + checkForModifiedFiles: false diff --git a/change/@fluentui-web-components-06a3ebaf-3485-4ea9-a024-ff17305e1f88.json b/change/@fluentui-web-components-06a3ebaf-3485-4ea9-a024-ff17305e1f88.json new file mode 100644 index 0000000000000..c2cb4822582aa --- /dev/null +++ b/change/@fluentui-web-components-06a3ebaf-3485-4ea9-a024-ff17305e1f88.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: bump web-components to 3.0.0-alpha.0", + "packageName": "@fluentui/web-components", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/package.json b/package.json index abacdd7ce6d2b..c341bd79c3662 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "builddemo": "yarn build --to public-docsite-resources", "buildto": "lage build --verbose --to", "bundle": "lage bundle --verbose", - "change": "beachball change --no-commit", - "check:change": "beachball check", + "change": "beachball change --no-commit -b web-components-v3", + "check:change": "beachball check -b web-components-v3", "check:modified-files": "node -r ./scripts/ts-node/register ./scripts/executors/check-for-modified-files", "check:affected": "node ./scripts/executors/checkIfPackagesAffected.js", "check:installed-dependencies-versions": "satisfied --no-peers --skip-invalid", diff --git a/packages/web-components/package.json b/packages/web-components/package.json index a25ee9881d51f..1d87121cbdbd3 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "2.6.1", + "version": "3.0.0-alpha.0", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" @@ -77,5 +77,13 @@ "@microsoft/fast-foundation": "^2.49.6", "@microsoft/fast-web-utilities": "^5.4.0", "tslib": "^2.1.0" + }, + "beachball": { + "disallowedChangeTypes": [ + "major", + "minor", + "patch" + ], + "tag": "alpha" } } diff --git a/scripts/beachball/check-wc-3-changefiles.js b/scripts/beachball/check-wc-3-changefiles.js new file mode 100644 index 0000000000000..8ed3ca8301bfb --- /dev/null +++ b/scripts/beachball/check-wc-3-changefiles.js @@ -0,0 +1,65 @@ +const path = require('path'); +const fs = require('fs'); + +/** + * @typedef {{ + type: 'none' | 'prerelease' | 'patch' | 'minor' | 'major'; + comment: string; + packageName: string; + email: string; + dependentChangeType: 'none' | 'patch'; +}} ChangeFile + */ + +const isExecutedFromCli = require.main === module; + +if (isExecutedFromCli) { + const changefilesRootPath = path.resolve(__dirname, '../../change'); + main(changefilesRootPath); +} + +/** + * Utility for web-components-v3 development branch to double check we dont accidentally introduce chain of changes, + * which could result in releasing/bumping monorepo packages beside `@fluentui/web-components` ! + * + * ⚠️ TODO: + * - This functionality NEEDS to be REMOVED prior merging to master + * - Usage needs to be removed from .github/workflows/check-packages.yml + */ +function main(/** @type {string} */ root) { + const changeFiles = fs.readdirSync(root, 'utf8'); + + const invalidChangeFiles = /** @type string [] */ (changeFiles + .map(changeFilePath => { + const filePath = path.join(root, changeFilePath); + /** @type {ChangeFile} */ + const content = JSON.parse(fs.readFileSync(filePath, 'utf-8')); + + if (content.packageName === '@fluentui/web-components') { + return; + } + + if (content.type !== 'none' || content.dependentChangeType !== 'none') { + return changeFilePath; + } + }) + .filter(Boolean)); + + if (invalidChangeFiles.length > 0) { + console.error('================'); + console.error(`You commited changefiles with not allowed type/dependentChangeType!`); + console.error( + `Changefiles that are not for @fluentui/web-components need to have type and dependentChangeType set to "none"`, + ); + console.error(); + console.error('Invalid change files:'); + console.error(invalidChangeFiles.join('\n')); + console.error('================'); + + process.exit(1); + } + + console.log('✅ All changefiles are valid.'); +} + +exports.main = main; diff --git a/scripts/beachball/check-wc-3-changefiles.spec.ts b/scripts/beachball/check-wc-3-changefiles.spec.ts new file mode 100644 index 0000000000000..f53b761cff3d5 --- /dev/null +++ b/scripts/beachball/check-wc-3-changefiles.spec.ts @@ -0,0 +1,104 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import tmp from 'tmp'; +import { main } from './check-wc-3-changefiles'; +import type { ChangeFile } from './check-wc-3-changefiles'; + +tmp.setGracefulCleanup(); + +function setup(changefiles: Array) { + const root = tmp.dirSync({ prefix: 'changefiles', unsafeCleanup: true }).name; + const changesRoot = path.join(root, 'change'); + + fs.mkdirSync(changesRoot); + changefiles.forEach((change, idx) => { + const changeFilePath = path.join(changesRoot, `${change.packageName.replace('/', '-')}-${idx}-abc.json`); + // console.log(`creating: ${changeFilePath}`); + + fs.writeFileSync(changeFilePath, JSON.stringify(change, null, 2), 'utf-8'); + }); + + const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + const processExitSpy = jest.spyOn(process, 'exit').mockImplementation((() => {}) as any); + + return { root: changesRoot, consoleErrorSpy, processExitSpy }; +} + +describe(`Name of the group`, () => { + it(`should pass if only valid changefiles exist`, () => { + const changeFiles: Array = [ + { + type: 'none', + comment: 'change one', + email: 'foo@bar.com', + dependentChangeType: 'none', + packageName: '@fluentui/react-text', + }, + { + type: 'prerelease', + comment: 'change one', + email: 'foo@bar.com', + dependentChangeType: 'patch', + packageName: '@fluentui/web-components', + }, + ]; + const { root, consoleErrorSpy, processExitSpy } = setup(changeFiles); + main(root); + + expect(processExitSpy).not.toHaveBeenCalled(); + expect(consoleErrorSpy).not.toHaveBeenCalled(); + }); + + it(`should fail if there is invalid changefile`, () => { + const changeFiles: Array = [ + { + type: 'patch', + comment: 'change one', + email: 'foo@bar.com', + dependentChangeType: 'patch', + packageName: '@fluentui/react-card', + }, + { + type: 'none', + comment: 'change one', + email: 'foo@bar.com', + dependentChangeType: 'patch', + packageName: '@fluentui/react-image', + }, + { + type: 'patch', + comment: 'change one', + email: 'foo@bar.com', + dependentChangeType: 'none', + packageName: '@fluentui/react-text', + }, + { + type: 'prerelease', + comment: 'change one', + email: 'foo@bar.com', + dependentChangeType: 'patch', + packageName: '@fluentui/web-components', + }, + ]; + const { root, consoleErrorSpy, processExitSpy } = setup(changeFiles); + main(root); + + expect(processExitSpy).toHaveBeenCalledWith(1); + + expect(consoleErrorSpy).toHaveBeenCalled(); + const logs = consoleErrorSpy.mock.calls.flat(); + + expect(logs).toMatchInlineSnapshot(` + Array [ + "================", + "You commited changefiles with not allowed type/dependentChangeType!", + "Changefiles that are not for @fluentui/web-components need to have type and dependentChangeType set to \\"none\\"", + "Invalid change files:", + "@fluentui-react-card-0-abc.json + @fluentui-react-image-1-abc.json + @fluentui-react-text-2-abc.json", + "================", + ] + `); + }); +}); diff --git a/scripts/beachball/config.test.ts b/scripts/beachball/config.test.ts index defc43c2d61cc..80d31fdc3cd68 100644 --- a/scripts/beachball/config.test.ts +++ b/scripts/beachball/config.test.ts @@ -1,5 +1,6 @@ import v8Config from './release-v8.config'; import vNextConfig from './release-vNext.config'; +import webComponentsConfig from './release-web-components.config'; import { config as sharedConfig } from './shared.config'; describe(`beachball configs`, () => { @@ -77,4 +78,19 @@ describe(`beachball configs`, () => { }, ]); }); + + it(`should generate web-components release config`, () => { + expect(webComponentsConfig.scope).toEqual( + expect.arrayContaining([ + 'packages/web-components', + '!packages/fluentui/*', + '!apps/*', + '!apps/perf-test-react-components', + '!apps/vr-tests-react-components', + '!packages/react-components/react-components', + ]), + ); + expect(webComponentsConfig.scope.some(scope => scope.startsWith('!packages/react-'))).toBe(true); + expect(webComponentsConfig.changelog).toEqual(sharedConfig.changelog); + }); }); diff --git a/scripts/beachball/release-web-components.config.js b/scripts/beachball/release-web-components.config.js new file mode 100644 index 0000000000000..a85e627d58657 --- /dev/null +++ b/scripts/beachball/release-web-components.config.js @@ -0,0 +1,21 @@ +if (process.env.NODE_ENV !== 'test') { + require('../ts-node-register'); +} + +const { getConfig } = require('./utils'); +const { config: sharedConfig } = require('./shared.config'); + +const { scope } = getConfig({ version: 'web-components' }); + +/** + * @type {typeof sharedConfig} + */ +const config = { + ...sharedConfig, + scope: [...sharedConfig.scope, ...scope], + changelog: { + ...sharedConfig.changelog, + }, +}; + +module.exports = config; diff --git a/scripts/beachball/utils.ts b/scripts/beachball/utils.ts index fc7cdc738b7e9..d2a901f99029d 100644 --- a/scripts/beachball/utils.ts +++ b/scripts/beachball/utils.ts @@ -7,6 +7,7 @@ import { getAllPackageInfo, isConvergedPackage } from '@fluentui/scripts-monorep * vNext scope includes all packages that have version > 8.x and shared internal packages that need versions bumped. * @returns {string[]} Array of package paths for beachball scope */ +export function getConfig({ version }: { version: 'web-components' }): { scope: string[] }; export function getConfig({ version }: { version: 'v8' }): { scope: string[] }; export function getConfig({ version }: { version: 'vNext' }): { scope: string[]; @@ -16,9 +17,17 @@ export function getConfig({ version }: { version: 'vNext' }): { include: string[]; }; }; -export function getConfig({ version }: { version: 'v8' | 'vNext' }) { +export function getConfig({ version }: { version: 'v8' | 'vNext' | 'web-components' }) { const vNextPackagePaths = getVNextPackagePaths(); + if (version === 'web-components') { + const allPackageInfo = getAllPackageInfo(); + const ignoreVNextScope = vNextPackagePaths.map(path => `!${path}`); + return { + scope: [allPackageInfo['@fluentui/web-components'].packagePath, '!apps/*', ...ignoreVNextScope], + }; + } + if (version === 'vNext') { return { scope: [...vNextPackagePaths], From 3010a9d02d8e3f34841d493a9846f414a6fcfa0c Mon Sep 17 00:00:00 2001 From: Miroslav Stastny Date: Wed, 21 Dec 2022 18:59:51 +0100 Subject: [PATCH 005/203] feat(wc): Add v9-compatible themes (#25660) * bump FAST dependencies * Add theme tokens (from react-theme) * Add theme switcher to storybook * deduplicate packages * fix yarn.lock * Replace @fluentui/react-theme with @fluentui/tokens * change file * address PR comments --- ...-7d0424dc-fe77-4d05-b911-295ca60d04fd.json | 7 + .../.storybook/preview-body.html | 9 + packages/web-components/.storybook/preview.js | 37 +- packages/web-components/package.json | 8 +- .../web-components/public/theme-switch.ts | 13 + .../web-components/src/theme/design-tokens.ts | 383 ++++++++++++++++++ packages/web-components/src/theme/index.ts | 2 + .../web-components/src/theme/set-theme.ts | 14 + .../web-components/src/theme/theme.stories.ts | 24 ++ yarn.lock | 52 ++- 10 files changed, 490 insertions(+), 59 deletions(-) create mode 100644 change/@fluentui-web-components-7d0424dc-fe77-4d05-b911-295ca60d04fd.json create mode 100644 packages/web-components/.storybook/preview-body.html create mode 100644 packages/web-components/public/theme-switch.ts create mode 100644 packages/web-components/src/theme/design-tokens.ts create mode 100644 packages/web-components/src/theme/index.ts create mode 100644 packages/web-components/src/theme/set-theme.ts create mode 100644 packages/web-components/src/theme/theme.stories.ts diff --git a/change/@fluentui-web-components-7d0424dc-fe77-4d05-b911-295ca60d04fd.json b/change/@fluentui-web-components-7d0424dc-fe77-4d05-b911-295ca60d04fd.json new file mode 100644 index 0000000000000..a203b8bda0502 --- /dev/null +++ b/change/@fluentui-web-components-7d0424dc-fe77-4d05-b911-295ca60d04fd.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Add initial theme", + "packageName": "@fluentui/web-components", + "email": "miroslav.stastny@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/.storybook/preview-body.html b/packages/web-components/.storybook/preview-body.html new file mode 100644 index 0000000000000..93e32a40560db --- /dev/null +++ b/packages/web-components/.storybook/preview-body.html @@ -0,0 +1,9 @@ +
+ + +
diff --git a/packages/web-components/.storybook/preview.js b/packages/web-components/.storybook/preview.js index f240e287648af..c1340a5c49bde 100644 --- a/packages/web-components/.storybook/preview.js +++ b/packages/web-components/.storybook/preview.js @@ -1,10 +1,16 @@ -import { addons } from '@storybook/addons'; -import { DOCS_RENDERED } from '@storybook/core-events'; import * as Fluent from '../src/index-rollup'; import webcomponentsTheme from './theme'; +import { switchTheme } from '../public/theme-switch'; Fluent; +function changeTheme(e) { + switchTheme(e.target.value); +} + +document.getElementById('theme-switch').addEventListener('change', changeTheme, false); +switchTheme('web-light'); + export const parameters = { layout: 'fullscreen', controls: { expanded: true }, @@ -14,18 +20,7 @@ export const parameters = { }, options: { storySort: { - order: [ - 'Getting Started', - ['Overview', 'Installation', 'Styling'], - 'Components', - 'Integrations', - ['Introduction'], - 'Design System', - ['Design Tokens', 'Color Explorer', 'High Contrast'], - 'Resources', - ['Browser Support', 'FAQ', 'License', 'Security'], - '*', - ], + order: [], method: 'alphabetical', }, }, @@ -33,17 +28,3 @@ export const parameters = { theme: webcomponentsTheme, // override the default Storybook theme with a custom fluent theme }, }; - -addons.getChannel().addListener(DOCS_RENDERED, name => { - if (name.toLowerCase().includes('accordion') || name.toLowerCase().includes('card')) { - fillColor.setValueFor(document.body, neutralLayer2); - } else { - fillColor.setValueFor(document.body, neutralLayer1); - } - - if (name.toLowerCase().includes('color-explorer')) { - document.body.classList.add('custom-fullscreen'); - } else { - document.body.classList.remove('custom-fullscreen'); - } -}); diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 1d87121cbdbd3..e59096943dae0 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -72,10 +72,10 @@ "mocha": "7.2.0" }, "dependencies": { - "@microsoft/fast-colors": "^5.3.0", - "@microsoft/fast-element": "^1.13.0", - "@microsoft/fast-foundation": "^2.49.6", - "@microsoft/fast-web-utilities": "^5.4.0", + "@microsoft/fast-element": "^2.0.0-beta.17", + "@microsoft/fast-foundation": "^3.0.0-alpha.21", + "@microsoft/fast-web-utilities": "^6.0.0", + "@fluentui/tokens": "1.0.0-alpha.2", "tslib": "^2.1.0" }, "beachball": { diff --git a/packages/web-components/public/theme-switch.ts b/packages/web-components/public/theme-switch.ts new file mode 100644 index 0000000000000..86f4cbb264a43 --- /dev/null +++ b/packages/web-components/public/theme-switch.ts @@ -0,0 +1,13 @@ +import { teamsDarkTheme, teamsLightTheme, webDarkTheme, webLightTheme } from '@fluentui/tokens'; +import { setTheme } from '../src/theme'; + +const themes = { + 'web-light': webLightTheme, + 'web-dark': webDarkTheme, + 'teams-light': teamsLightTheme, + 'teams-dark': teamsDarkTheme, +}; + +export function switchTheme(themeName: keyof typeof themes) { + setTheme(themes[themeName]); +} diff --git a/packages/web-components/src/theme/design-tokens.ts b/packages/web-components/src/theme/design-tokens.ts new file mode 100644 index 0000000000000..aaed69106d57f --- /dev/null +++ b/packages/web-components/src/theme/design-tokens.ts @@ -0,0 +1,383 @@ +import { DesignToken } from '@microsoft/fast-foundation'; + +const { create } = DesignToken; + +export const borderRadiusNone = create('borderRadiusNone'); +export const borderRadiusSmall = create('borderRadiusSmall'); +export const borderRadiusMedium = create('borderRadiusMedium'); +export const borderRadiusLarge = create('borderRadiusLarge'); +export const borderRadiusXLarge = create('borderRadiusXLarge'); +export const borderRadiusCircular = create('borderRadiusCircular'); +export const fontSizeBase100 = create('fontSizeBase100'); +export const fontSizeBase200 = create('fontSizeBase200'); +export const fontSizeBase300 = create('fontSizeBase300'); +export const fontSizeBase400 = create('fontSizeBase400'); +export const fontSizeBase500 = create('fontSizeBase500'); +export const fontSizeBase600 = create('fontSizeBase600'); +export const fontSizeHero700 = create('fontSizeHero700'); +export const fontSizeHero800 = create('fontSizeHero800'); +export const fontSizeHero900 = create('fontSizeHero900'); +export const fontSizeHero1000 = create('fontSizeHero1000'); +export const lineHeightBase100 = create('lineHeightBase100'); +export const lineHeightBase200 = create('lineHeightBase200'); +export const lineHeightBase300 = create('lineHeightBase300'); +export const lineHeightBase400 = create('lineHeightBase400'); +export const lineHeightBase500 = create('lineHeightBase500'); +export const lineHeightBase600 = create('lineHeightBase600'); +export const lineHeightHero700 = create('lineHeightHero700'); +export const lineHeightHero800 = create('lineHeightHero800'); +export const lineHeightHero900 = create('lineHeightHero900'); +export const lineHeightHero1000 = create('lineHeightHero1000'); +export const fontFamilyBase = create('fontFamilyBase'); +export const fontFamilyMonospace = create('fontFamilyMonospace'); +export const fontFamilyNumeric = create('fontFamilyNumeric'); +export const fontWeightRegular = create('fontWeightRegular'); +export const fontWeightMedium = create('fontWeightMedium'); +export const fontWeightSemibold = create('fontWeightSemibold'); +export const fontWeightBold = create('fontWeightBold'); +export const strokeWidthThin = create('strokeWidthThin'); +export const strokeWidthThick = create('strokeWidthThick'); +export const strokeWidthThicker = create('strokeWidthThicker'); +export const strokeWidthThickest = create('strokeWidthThickest'); +export const spacingHorizontalNone = create('spacingHorizontalNone'); +export const spacingHorizontalXXS = create('spacingHorizontalXXS'); +export const spacingHorizontalXS = create('spacingHorizontalXS'); +export const spacingHorizontalSNudge = create('spacingHorizontalSNudge'); +export const spacingHorizontalS = create('spacingHorizontalS'); +export const spacingHorizontalMNudge = create('spacingHorizontalMNudge'); +export const spacingHorizontalM = create('spacingHorizontalM'); +export const spacingHorizontalL = create('spacingHorizontalL'); +export const spacingHorizontalXL = create('spacingHorizontalXL'); +export const spacingHorizontalXXL = create('spacingHorizontalXXL'); +export const spacingHorizontalXXXL = create('spacingHorizontalXXXL'); +export const spacingVerticalNone = create('spacingVerticalNone'); +export const spacingVerticalXXS = create('spacingVerticalXXS'); +export const spacingVerticalXS = create('spacingVerticalXS'); +export const spacingVerticalSNudge = create('spacingVerticalSNudge'); +export const spacingVerticalS = create('spacingVerticalS'); +export const spacingVerticalMNudge = create('spacingVerticalMNudge'); +export const spacingVerticalM = create('spacingVerticalM'); +export const spacingVerticalL = create('spacingVerticalL'); +export const spacingVerticalXL = create('spacingVerticalXL'); +export const spacingVerticalXXL = create('spacingVerticalXXL'); +export const spacingVerticalXXXL = create('spacingVerticalXXXL'); +export const durationUltraFast = create('durationUltraFast'); +export const durationFaster = create('durationFaster'); +export const durationFast = create('durationFast'); +export const durationNormal = create('durationNormal'); +export const durationSlow = create('durationSlow'); +export const durationSlower = create('durationSlower'); +export const durationUltraSlow = create('durationUltraSlow'); +export const curveAccelerateMax = create('curveAccelerateMax'); +export const curveAccelerateMid = create('curveAccelerateMid'); +export const curveAccelerateMin = create('curveAccelerateMin'); +export const curveDecelerateMax = create('curveDecelerateMax'); +export const curveDecelerateMid = create('curveDecelerateMid'); +export const curveDecelerateMin = create('curveDecelerateMin'); +export const curveEasyEaseMax = create('curveEasyEaseMax'); +export const curveEasyEase = create('curveEasyEase'); +export const curveLinear = create('curveLinear'); +export const colorNeutralForeground1 = create('colorNeutralForeground1'); +export const colorNeutralForeground1Hover = create('colorNeutralForeground1Hover'); +export const colorNeutralForeground1Pressed = create('colorNeutralForeground1Pressed'); +export const colorNeutralForeground1Selected = create('colorNeutralForeground1Selected'); +export const colorNeutralForeground2 = create('colorNeutralForeground2'); +export const colorNeutralForeground2Hover = create('colorNeutralForeground2Hover'); +export const colorNeutralForeground2Pressed = create('colorNeutralForeground2Pressed'); +export const colorNeutralForeground2Selected = create('colorNeutralForeground2Selected'); +export const colorNeutralForeground2BrandHover = create('colorNeutralForeground2BrandHover'); +export const colorNeutralForeground2BrandPressed = create('colorNeutralForeground2BrandPressed'); +export const colorNeutralForeground2BrandSelected = create('colorNeutralForeground2BrandSelected'); +export const colorNeutralForeground3 = create('colorNeutralForeground3'); +export const colorNeutralForeground3Hover = create('colorNeutralForeground3Hover'); +export const colorNeutralForeground3Pressed = create('colorNeutralForeground3Pressed'); +export const colorNeutralForeground3Selected = create('colorNeutralForeground3Selected'); +export const colorNeutralForeground3BrandHover = create('colorNeutralForeground3BrandHover'); +export const colorNeutralForeground3BrandPressed = create('colorNeutralForeground3BrandPressed'); +export const colorNeutralForeground3BrandSelected = create('colorNeutralForeground3BrandSelected'); +export const colorNeutralForeground4 = create('colorNeutralForeground4'); +export const colorNeutralForegroundDisabled = create('colorNeutralForegroundDisabled'); +export const colorNeutralForegroundInvertedDisabled = create('colorNeutralForegroundInvertedDisabled'); +export const colorBrandForegroundLink = create('colorBrandForegroundLink'); +export const colorBrandForegroundLinkHover = create('colorBrandForegroundLinkHover'); +export const colorBrandForegroundLinkPressed = create('colorBrandForegroundLinkPressed'); +export const colorBrandForegroundLinkSelected = create('colorBrandForegroundLinkSelected'); +export const colorNeutralForeground2Link = create('colorNeutralForeground2Link'); +export const colorNeutralForeground2LinkHover = create('colorNeutralForeground2LinkHover'); +export const colorNeutralForeground2LinkPressed = create('colorNeutralForeground2LinkPressed'); +export const colorNeutralForeground2LinkSelected = create('colorNeutralForeground2LinkSelected'); +export const colorCompoundBrandForeground1 = create('colorCompoundBrandForeground1'); +export const colorCompoundBrandForeground1Hover = create('colorCompoundBrandForeground1Hover'); +export const colorCompoundBrandForeground1Pressed = create('colorCompoundBrandForeground1Pressed'); +export const colorBrandForeground1 = create('colorBrandForeground1'); +export const colorBrandForeground2 = create('colorBrandForeground2'); +export const colorNeutralForeground1Static = create('colorNeutralForeground1Static'); +export const colorNeutralForegroundStaticInverted = create('colorNeutralForegroundStaticInverted'); +export const colorNeutralForegroundInverted = create('colorNeutralForegroundInverted'); +export const colorNeutralForegroundInvertedHover = create('colorNeutralForegroundInvertedHover'); +export const colorNeutralForegroundInvertedPressed = create('colorNeutralForegroundInvertedPressed'); +export const colorNeutralForegroundInvertedSelected = create('colorNeutralForegroundInvertedSelected'); +export const colorNeutralForegroundInverted2 = create('colorNeutralForegroundInverted2'); +export const colorNeutralForegroundOnBrand = create('colorNeutralForegroundOnBrand'); +export const colorNeutralForegroundInvertedLink = create('colorNeutralForegroundInvertedLink'); +export const colorNeutralForegroundInvertedLinkHover = create('colorNeutralForegroundInvertedLinkHover'); +export const colorNeutralForegroundInvertedLinkPressed = create('colorNeutralForegroundInvertedLinkPressed'); +export const colorNeutralForegroundInvertedLinkSelected = create('colorNeutralForegroundInvertedLinkSelected'); +export const colorBrandForegroundInverted = create('colorBrandForegroundInverted'); +export const colorBrandForegroundInvertedHover = create('colorBrandForegroundInvertedHover'); +export const colorBrandForegroundInvertedPressed = create('colorBrandForegroundInvertedPressed'); +export const colorBrandForegroundOnLight = create('colorBrandForegroundOnLight'); +export const colorBrandForegroundOnLightHover = create('colorBrandForegroundOnLightHover'); +export const colorBrandForegroundOnLightPressed = create('colorBrandForegroundOnLightPressed'); +export const colorBrandForegroundOnLightSelected = create('colorBrandForegroundOnLightSelected'); +export const colorNeutralBackground1 = create('colorNeutralBackground1'); +export const colorNeutralBackground1Hover = create('colorNeutralBackground1Hover'); +export const colorNeutralBackground1Pressed = create('colorNeutralBackground1Pressed'); +export const colorNeutralBackground1Selected = create('colorNeutralBackground1Selected'); +export const colorNeutralBackground2 = create('colorNeutralBackground2'); +export const colorNeutralBackground2Hover = create('colorNeutralBackground2Hover'); +export const colorNeutralBackground2Pressed = create('colorNeutralBackground2Pressed'); +export const colorNeutralBackground2Selected = create('colorNeutralBackground2Selected'); +export const colorNeutralBackground3 = create('colorNeutralBackground3'); +export const colorNeutralBackground3Hover = create('colorNeutralBackground3Hover'); +export const colorNeutralBackground3Pressed = create('colorNeutralBackground3Pressed'); +export const colorNeutralBackground3Selected = create('colorNeutralBackground3Selected'); +export const colorNeutralBackground4 = create('colorNeutralBackground4'); +export const colorNeutralBackground4Hover = create('colorNeutralBackground4Hover'); +export const colorNeutralBackground4Pressed = create('colorNeutralBackground4Pressed'); +export const colorNeutralBackground4Selected = create('colorNeutralBackground4Selected'); +export const colorNeutralBackground5 = create('colorNeutralBackground5'); +export const colorNeutralBackground5Hover = create('colorNeutralBackground5Hover'); +export const colorNeutralBackground5Pressed = create('colorNeutralBackground5Pressed'); +export const colorNeutralBackground5Selected = create('colorNeutralBackground5Selected'); +export const colorNeutralBackground6 = create('colorNeutralBackground6'); +export const colorNeutralBackgroundInverted = create('colorNeutralBackgroundInverted'); +export const colorNeutralBackgroundStatic = create('colorNeutralBackgroundStatic'); +export const colorSubtleBackground = create('colorSubtleBackground'); +export const colorSubtleBackgroundHover = create('colorSubtleBackgroundHover'); +export const colorSubtleBackgroundPressed = create('colorSubtleBackgroundPressed'); +export const colorSubtleBackgroundSelected = create('colorSubtleBackgroundSelected'); +export const colorSubtleBackgroundLightAlphaHover = create('colorSubtleBackgroundLightAlphaHover'); +export const colorSubtleBackgroundLightAlphaPressed = create('colorSubtleBackgroundLightAlphaPressed'); +export const colorSubtleBackgroundLightAlphaSelected = create('colorSubtleBackgroundLightAlphaSelected'); +export const colorSubtleBackgroundInverted = create('colorSubtleBackgroundInverted'); +export const colorSubtleBackgroundInvertedHover = create('colorSubtleBackgroundInvertedHover'); +export const colorSubtleBackgroundInvertedPressed = create('colorSubtleBackgroundInvertedPressed'); +export const colorSubtleBackgroundInvertedSelected = create('colorSubtleBackgroundInvertedSelected'); +export const colorTransparentBackground = create('colorTransparentBackground'); +export const colorTransparentBackgroundHover = create('colorTransparentBackgroundHover'); +export const colorTransparentBackgroundPressed = create('colorTransparentBackgroundPressed'); +export const colorTransparentBackgroundSelected = create('colorTransparentBackgroundSelected'); +export const colorNeutralBackgroundDisabled = create('colorNeutralBackgroundDisabled'); +export const colorNeutralBackgroundInvertedDisabled = create('colorNeutralBackgroundInvertedDisabled'); +export const colorNeutralStencil1 = create('colorNeutralStencil1'); +export const colorNeutralStencil2 = create('colorNeutralStencil2'); +export const colorBackgroundOverlay = create('colorBackgroundOverlay'); +export const colorScrollbarOverlay = create('colorScrollbarOverlay'); +export const colorBrandBackground = create('colorBrandBackground'); +export const colorBrandBackgroundHover = create('colorBrandBackgroundHover'); +export const colorBrandBackgroundPressed = create('colorBrandBackgroundPressed'); +export const colorBrandBackgroundSelected = create('colorBrandBackgroundSelected'); +export const colorCompoundBrandBackground = create('colorCompoundBrandBackground'); +export const colorCompoundBrandBackgroundHover = create('colorCompoundBrandBackgroundHover'); +export const colorCompoundBrandBackgroundPressed = create('colorCompoundBrandBackgroundPressed'); +export const colorBrandBackgroundStatic = create('colorBrandBackgroundStatic'); +export const colorBrandBackground2 = create('colorBrandBackground2'); +export const colorBrandBackgroundInverted = create('colorBrandBackgroundInverted'); +export const colorBrandBackgroundInvertedHover = create('colorBrandBackgroundInvertedHover'); +export const colorBrandBackgroundInvertedPressed = create('colorBrandBackgroundInvertedPressed'); +export const colorBrandBackgroundInvertedSelected = create('colorBrandBackgroundInvertedSelected'); +export const colorNeutralStrokeAccessible = create('colorNeutralStrokeAccessible'); +export const colorNeutralStrokeAccessibleHover = create('colorNeutralStrokeAccessibleHover'); +export const colorNeutralStrokeAccessiblePressed = create('colorNeutralStrokeAccessiblePressed'); +export const colorNeutralStrokeAccessibleSelected = create('colorNeutralStrokeAccessibleSelected'); +export const colorNeutralStroke1 = create('colorNeutralStroke1'); +export const colorNeutralStroke1Hover = create('colorNeutralStroke1Hover'); +export const colorNeutralStroke1Pressed = create('colorNeutralStroke1Pressed'); +export const colorNeutralStroke1Selected = create('colorNeutralStroke1Selected'); +export const colorNeutralStroke2 = create('colorNeutralStroke2'); +export const colorNeutralStroke3 = create('colorNeutralStroke3'); +export const colorNeutralStrokeOnBrand = create('colorNeutralStrokeOnBrand'); +export const colorNeutralStrokeOnBrand2 = create('colorNeutralStrokeOnBrand2'); +export const colorNeutralStrokeOnBrand2Hover = create('colorNeutralStrokeOnBrand2Hover'); +export const colorNeutralStrokeOnBrand2Pressed = create('colorNeutralStrokeOnBrand2Pressed'); +export const colorNeutralStrokeOnBrand2Selected = create('colorNeutralStrokeOnBrand2Selected'); +export const colorBrandStroke1 = create('colorBrandStroke1'); +export const colorBrandStroke2 = create('colorBrandStroke2'); +export const colorCompoundBrandStroke = create('colorCompoundBrandStroke'); +export const colorCompoundBrandStrokeHover = create('colorCompoundBrandStrokeHover'); +export const colorCompoundBrandStrokePressed = create('colorCompoundBrandStrokePressed'); +export const colorNeutralStrokeDisabled = create('colorNeutralStrokeDisabled'); +export const colorNeutralStrokeInvertedDisabled = create('colorNeutralStrokeInvertedDisabled'); +export const colorTransparentStroke = create('colorTransparentStroke'); +export const colorTransparentStrokeInteractive = create('colorTransparentStrokeInteractive'); +export const colorTransparentStrokeDisabled = create('colorTransparentStrokeDisabled'); +export const colorStrokeFocus1 = create('colorStrokeFocus1'); +export const colorStrokeFocus2 = create('colorStrokeFocus2'); +export const colorNeutralShadowAmbient = create('colorNeutralShadowAmbient'); +export const colorNeutralShadowKey = create('colorNeutralShadowKey'); +export const colorNeutralShadowAmbientLighter = create('colorNeutralShadowAmbientLighter'); +export const colorNeutralShadowKeyLighter = create('colorNeutralShadowKeyLighter'); +export const colorNeutralShadowAmbientDarker = create('colorNeutralShadowAmbientDarker'); +export const colorNeutralShadowKeyDarker = create('colorNeutralShadowKeyDarker'); +export const colorBrandShadowAmbient = create('colorBrandShadowAmbient'); +export const colorBrandShadowKey = create('colorBrandShadowKey'); +export const colorPaletteRedBackground1 = create('colorPaletteRedBackground1'); +export const colorPaletteRedBackground2 = create('colorPaletteRedBackground2'); +export const colorPaletteRedBackground3 = create('colorPaletteRedBackground3'); +export const colorPaletteRedForeground1 = create('colorPaletteRedForeground1'); +export const colorPaletteRedForeground2 = create('colorPaletteRedForeground2'); +export const colorPaletteRedForeground3 = create('colorPaletteRedForeground3'); +export const colorPaletteRedBorderActive = create('colorPaletteRedBorderActive'); +export const colorPaletteRedBorder1 = create('colorPaletteRedBorder1'); +export const colorPaletteRedBorder2 = create('colorPaletteRedBorder2'); +export const colorPaletteGreenBackground1 = create('colorPaletteGreenBackground1'); +export const colorPaletteGreenBackground2 = create('colorPaletteGreenBackground2'); +export const colorPaletteGreenBackground3 = create('colorPaletteGreenBackground3'); +export const colorPaletteGreenForeground1 = create('colorPaletteGreenForeground1'); +export const colorPaletteGreenForeground2 = create('colorPaletteGreenForeground2'); +export const colorPaletteGreenForeground3 = create('colorPaletteGreenForeground3'); +export const colorPaletteGreenBorderActive = create('colorPaletteGreenBorderActive'); +export const colorPaletteGreenBorder1 = create('colorPaletteGreenBorder1'); +export const colorPaletteGreenBorder2 = create('colorPaletteGreenBorder2'); +export const colorPaletteDarkOrangeBackground1 = create('colorPaletteDarkOrangeBackground1'); +export const colorPaletteDarkOrangeBackground2 = create('colorPaletteDarkOrangeBackground2'); +export const colorPaletteDarkOrangeBackground3 = create('colorPaletteDarkOrangeBackground3'); +export const colorPaletteDarkOrangeForeground1 = create('colorPaletteDarkOrangeForeground1'); +export const colorPaletteDarkOrangeForeground2 = create('colorPaletteDarkOrangeForeground2'); +export const colorPaletteDarkOrangeForeground3 = create('colorPaletteDarkOrangeForeground3'); +export const colorPaletteDarkOrangeBorderActive = create('colorPaletteDarkOrangeBorderActive'); +export const colorPaletteDarkOrangeBorder1 = create('colorPaletteDarkOrangeBorder1'); +export const colorPaletteDarkOrangeBorder2 = create('colorPaletteDarkOrangeBorder2'); +export const colorPaletteYellowBackground1 = create('colorPaletteYellowBackground1'); +export const colorPaletteYellowBackground2 = create('colorPaletteYellowBackground2'); +export const colorPaletteYellowBackground3 = create('colorPaletteYellowBackground3'); +export const colorPaletteYellowForeground1 = create('colorPaletteYellowForeground1'); +export const colorPaletteYellowForeground2 = create('colorPaletteYellowForeground2'); +export const colorPaletteYellowForeground3 = create('colorPaletteYellowForeground3'); +export const colorPaletteYellowBorderActive = create('colorPaletteYellowBorderActive'); +export const colorPaletteYellowBorder1 = create('colorPaletteYellowBorder1'); +export const colorPaletteYellowBorder2 = create('colorPaletteYellowBorder2'); +export const colorPaletteBerryBackground1 = create('colorPaletteBerryBackground1'); +export const colorPaletteBerryBackground2 = create('colorPaletteBerryBackground2'); +export const colorPaletteBerryBackground3 = create('colorPaletteBerryBackground3'); +export const colorPaletteBerryForeground1 = create('colorPaletteBerryForeground1'); +export const colorPaletteBerryForeground2 = create('colorPaletteBerryForeground2'); +export const colorPaletteBerryForeground3 = create('colorPaletteBerryForeground3'); +export const colorPaletteBerryBorderActive = create('colorPaletteBerryBorderActive'); +export const colorPaletteBerryBorder1 = create('colorPaletteBerryBorder1'); +export const colorPaletteBerryBorder2 = create('colorPaletteBerryBorder2'); +export const colorPaletteLightGreenBackground1 = create('colorPaletteLightGreenBackground1'); +export const colorPaletteLightGreenBackground2 = create('colorPaletteLightGreenBackground2'); +export const colorPaletteLightGreenBackground3 = create('colorPaletteLightGreenBackground3'); +export const colorPaletteLightGreenForeground1 = create('colorPaletteLightGreenForeground1'); +export const colorPaletteLightGreenForeground2 = create('colorPaletteLightGreenForeground2'); +export const colorPaletteLightGreenForeground3 = create('colorPaletteLightGreenForeground3'); +export const colorPaletteLightGreenBorderActive = create('colorPaletteLightGreenBorderActive'); +export const colorPaletteLightGreenBorder1 = create('colorPaletteLightGreenBorder1'); +export const colorPaletteLightGreenBorder2 = create('colorPaletteLightGreenBorder2'); +export const colorPaletteMarigoldBackground1 = create('colorPaletteMarigoldBackground1'); +export const colorPaletteMarigoldBackground2 = create('colorPaletteMarigoldBackground2'); +export const colorPaletteMarigoldBackground3 = create('colorPaletteMarigoldBackground3'); +export const colorPaletteMarigoldForeground1 = create('colorPaletteMarigoldForeground1'); +export const colorPaletteMarigoldForeground2 = create('colorPaletteMarigoldForeground2'); +export const colorPaletteMarigoldForeground3 = create('colorPaletteMarigoldForeground3'); +export const colorPaletteMarigoldBorderActive = create('colorPaletteMarigoldBorderActive'); +export const colorPaletteMarigoldBorder1 = create('colorPaletteMarigoldBorder1'); +export const colorPaletteMarigoldBorder2 = create('colorPaletteMarigoldBorder2'); +export const colorPaletteDarkRedBackground2 = create('colorPaletteDarkRedBackground2'); +export const colorPaletteDarkRedForeground2 = create('colorPaletteDarkRedForeground2'); +export const colorPaletteDarkRedBorderActive = create('colorPaletteDarkRedBorderActive'); +export const colorPaletteCranberryBackground2 = create('colorPaletteCranberryBackground2'); +export const colorPaletteCranberryForeground2 = create('colorPaletteCranberryForeground2'); +export const colorPaletteCranberryBorderActive = create('colorPaletteCranberryBorderActive'); +export const colorPalettePumpkinBackground2 = create('colorPalettePumpkinBackground2'); +export const colorPalettePumpkinForeground2 = create('colorPalettePumpkinForeground2'); +export const colorPalettePumpkinBorderActive = create('colorPalettePumpkinBorderActive'); +export const colorPalettePeachBackground2 = create('colorPalettePeachBackground2'); +export const colorPalettePeachForeground2 = create('colorPalettePeachForeground2'); +export const colorPalettePeachBorderActive = create('colorPalettePeachBorderActive'); +export const colorPaletteGoldBackground2 = create('colorPaletteGoldBackground2'); +export const colorPaletteGoldForeground2 = create('colorPaletteGoldForeground2'); +export const colorPaletteGoldBorderActive = create('colorPaletteGoldBorderActive'); +export const colorPaletteBrassBackground2 = create('colorPaletteBrassBackground2'); +export const colorPaletteBrassForeground2 = create('colorPaletteBrassForeground2'); +export const colorPaletteBrassBorderActive = create('colorPaletteBrassBorderActive'); +export const colorPaletteBrownBackground2 = create('colorPaletteBrownBackground2'); +export const colorPaletteBrownForeground2 = create('colorPaletteBrownForeground2'); +export const colorPaletteBrownBorderActive = create('colorPaletteBrownBorderActive'); +export const colorPaletteForestBackground2 = create('colorPaletteForestBackground2'); +export const colorPaletteForestForeground2 = create('colorPaletteForestForeground2'); +export const colorPaletteForestBorderActive = create('colorPaletteForestBorderActive'); +export const colorPaletteSeafoamBackground2 = create('colorPaletteSeafoamBackground2'); +export const colorPaletteSeafoamForeground2 = create('colorPaletteSeafoamForeground2'); +export const colorPaletteSeafoamBorderActive = create('colorPaletteSeafoamBorderActive'); +export const colorPaletteDarkGreenBackground2 = create('colorPaletteDarkGreenBackground2'); +export const colorPaletteDarkGreenForeground2 = create('colorPaletteDarkGreenForeground2'); +export const colorPaletteDarkGreenBorderActive = create('colorPaletteDarkGreenBorderActive'); +export const colorPaletteLightTealBackground2 = create('colorPaletteLightTealBackground2'); +export const colorPaletteLightTealForeground2 = create('colorPaletteLightTealForeground2'); +export const colorPaletteLightTealBorderActive = create('colorPaletteLightTealBorderActive'); +export const colorPaletteTealBackground2 = create('colorPaletteTealBackground2'); +export const colorPaletteTealForeground2 = create('colorPaletteTealForeground2'); +export const colorPaletteTealBorderActive = create('colorPaletteTealBorderActive'); +export const colorPaletteSteelBackground2 = create('colorPaletteSteelBackground2'); +export const colorPaletteSteelForeground2 = create('colorPaletteSteelForeground2'); +export const colorPaletteSteelBorderActive = create('colorPaletteSteelBorderActive'); +export const colorPaletteBlueBackground2 = create('colorPaletteBlueBackground2'); +export const colorPaletteBlueForeground2 = create('colorPaletteBlueForeground2'); +export const colorPaletteBlueBorderActive = create('colorPaletteBlueBorderActive'); +export const colorPaletteRoyalBlueBackground2 = create('colorPaletteRoyalBlueBackground2'); +export const colorPaletteRoyalBlueForeground2 = create('colorPaletteRoyalBlueForeground2'); +export const colorPaletteRoyalBlueBorderActive = create('colorPaletteRoyalBlueBorderActive'); +export const colorPaletteCornflowerBackground2 = create('colorPaletteCornflowerBackground2'); +export const colorPaletteCornflowerForeground2 = create('colorPaletteCornflowerForeground2'); +export const colorPaletteCornflowerBorderActive = create('colorPaletteCornflowerBorderActive'); +export const colorPaletteNavyBackground2 = create('colorPaletteNavyBackground2'); +export const colorPaletteNavyForeground2 = create('colorPaletteNavyForeground2'); +export const colorPaletteNavyBorderActive = create('colorPaletteNavyBorderActive'); +export const colorPaletteLavenderBackground2 = create('colorPaletteLavenderBackground2'); +export const colorPaletteLavenderForeground2 = create('colorPaletteLavenderForeground2'); +export const colorPaletteLavenderBorderActive = create('colorPaletteLavenderBorderActive'); +export const colorPalettePurpleBackground2 = create('colorPalettePurpleBackground2'); +export const colorPalettePurpleForeground2 = create('colorPalettePurpleForeground2'); +export const colorPalettePurpleBorderActive = create('colorPalettePurpleBorderActive'); +export const colorPaletteGrapeBackground2 = create('colorPaletteGrapeBackground2'); +export const colorPaletteGrapeForeground2 = create('colorPaletteGrapeForeground2'); +export const colorPaletteGrapeBorderActive = create('colorPaletteGrapeBorderActive'); +export const colorPaletteLilacBackground2 = create('colorPaletteLilacBackground2'); +export const colorPaletteLilacForeground2 = create('colorPaletteLilacForeground2'); +export const colorPaletteLilacBorderActive = create('colorPaletteLilacBorderActive'); +export const colorPalettePinkBackground2 = create('colorPalettePinkBackground2'); +export const colorPalettePinkForeground2 = create('colorPalettePinkForeground2'); +export const colorPalettePinkBorderActive = create('colorPalettePinkBorderActive'); +export const colorPaletteMagentaBackground2 = create('colorPaletteMagentaBackground2'); +export const colorPaletteMagentaForeground2 = create('colorPaletteMagentaForeground2'); +export const colorPaletteMagentaBorderActive = create('colorPaletteMagentaBorderActive'); +export const colorPalettePlumBackground2 = create('colorPalettePlumBackground2'); +export const colorPalettePlumForeground2 = create('colorPalettePlumForeground2'); +export const colorPalettePlumBorderActive = create('colorPalettePlumBorderActive'); +export const colorPaletteBeigeBackground2 = create('colorPaletteBeigeBackground2'); +export const colorPaletteBeigeForeground2 = create('colorPaletteBeigeForeground2'); +export const colorPaletteBeigeBorderActive = create('colorPaletteBeigeBorderActive'); +export const colorPaletteMinkBackground2 = create('colorPaletteMinkBackground2'); +export const colorPaletteMinkForeground2 = create('colorPaletteMinkForeground2'); +export const colorPaletteMinkBorderActive = create('colorPaletteMinkBorderActive'); +export const colorPalettePlatinumBackground2 = create('colorPalettePlatinumBackground2'); +export const colorPalettePlatinumForeground2 = create('colorPalettePlatinumForeground2'); +export const colorPalettePlatinumBorderActive = create('colorPalettePlatinumBorderActive'); +export const colorPaletteAnchorBackground2 = create('colorPaletteAnchorBackground2'); +export const colorPaletteAnchorForeground2 = create('colorPaletteAnchorForeground2'); +export const colorPaletteAnchorBorderActive = create('colorPaletteAnchorBorderActive'); +export const shadow2 = create('shadow2'); +export const shadow4 = create('shadow4'); +export const shadow8 = create('shadow8'); +export const shadow16 = create('shadow16'); +export const shadow28 = create('shadow28'); +export const shadow64 = create('shadow64'); +export const shadow2Brand = create('shadow2Brand'); +export const shadow4Brand = create('shadow4Brand'); +export const shadow8Brand = create('shadow8Brand'); +export const shadow16Brand = create('shadow16Brand'); +export const shadow28Brand = create('shadow28Brand'); +export const shadow64Brand = create('shadow64Brand'); diff --git a/packages/web-components/src/theme/index.ts b/packages/web-components/src/theme/index.ts new file mode 100644 index 0000000000000..805ad62b80b66 --- /dev/null +++ b/packages/web-components/src/theme/index.ts @@ -0,0 +1,2 @@ +export * from './design-tokens'; +export { setTheme } from './set-theme'; diff --git a/packages/web-components/src/theme/set-theme.ts b/packages/web-components/src/theme/set-theme.ts new file mode 100644 index 0000000000000..7c86f95ab2ac5 --- /dev/null +++ b/packages/web-components/src/theme/set-theme.ts @@ -0,0 +1,14 @@ +import type { Theme } from '@fluentui/tokens'; +import * as tokens from './design-tokens'; + +const tokenNames = Object.keys(tokens); + +/** + * Sets the theme tokens on defaultNode. + * @param theme Flat object of theme token values. + */ +export const setTheme = (theme: Theme) => { + for (const t of tokenNames) { + tokens[t].withDefault(theme[t]); + } +}; diff --git a/packages/web-components/src/theme/theme.stories.ts b/packages/web-components/src/theme/theme.stories.ts new file mode 100644 index 0000000000000..183987d06c461 --- /dev/null +++ b/packages/web-components/src/theme/theme.stories.ts @@ -0,0 +1,24 @@ +import { DesignToken } from '@microsoft/fast-foundation'; +import * as tokens from '../theme/design-tokens'; + +DesignToken.registerDefaultStyleTarget(); + +export default { + title: 'Theme/Tokens', +}; + +export const Tokens = () => ` +
+

Theme Tokens

+

Debug story which uses theme tokens to style the element below.

+
colorNeutralForegroundOnBrand on colorBrandBackground with shadow28
+
+`; diff --git a/yarn.lock b/yarn.lock index 6dd111929b887..ceed30e4e4c46 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1949,7 +1949,7 @@ resolved "https://registry.yarnpkg.com/@floating-ui/devtools/-/devtools-0.2.1.tgz#3e8023e09ede273a7aa426e7911f3dac630024c5" integrity sha512-8PHJLbD6VhBh+LJ1uty/Bz30qs02NXCE5u8WpOhSewlYXUWl03GNXknr9AS2yaAWJEQaY27x7eByJs44gODBcw== -"@floating-ui/dom@^1.2.0": +"@floating-ui/dom@^1.0.3", "@floating-ui/dom@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.2.0.tgz#a60212069cc58961c478037c30eba4b191c75316" integrity sha512-QXzg57o1cjLz3cGETzKXjI3kx1xyS49DW9l7kV2jw2c8Yftd434t2hllX0sVGn2Q8MtcW/4pNm8bfE1/4n6mng== @@ -1987,6 +1987,13 @@ "@griffel/react" "^1.5.14" "@swc/helpers" "^0.5.1" +"@fluentui/tokens@1.0.0-alpha.2": + version "1.0.0-alpha.2" + resolved "https://registry.yarnpkg.com/@fluentui/tokens/-/tokens-1.0.0-alpha.2.tgz#890d8617ff40caa327f2c6810d7354f87c392555" + integrity sha512-Rd3xFE+ynAjpTgXwOWQnbw1jLqRrRvCgFTPtlqFlXK31lkNOz28f4HAHkNSXsFF95r/pM6EvJ+GtEoBhzfkdSw== + dependencies: + tslib "^2.1.0" + "@griffel/babel-preset@1.4.20", "@griffel/babel-preset@^1.4.20": version "1.4.20" resolved "https://registry.yarnpkg.com/@griffel/babel-preset/-/babel-preset-1.4.20.tgz#047eb62f104e7bea781820816263e7407fafe543" @@ -2650,30 +2657,26 @@ eslint-plugin-react "7.24.0" eslint-plugin-security "1.4.0" -"@microsoft/fast-colors@^5.3.0": - version "5.3.1" - resolved "https://registry.yarnpkg.com/@microsoft/fast-colors/-/fast-colors-5.3.1.tgz#defc59874176e42316be7e6d24c31885ead8ca56" - integrity sha512-72RZXVfCbwQzvo5sXXkuLXLT7rMeYaSf5r/6ewQiv/trBtqpWRm4DEH2EilHw/iWTBKOXs1qZNQndgUMa5n4LA== - -"@microsoft/fast-element@^1.13.0": - version "1.13.0" - resolved "https://registry.yarnpkg.com/@microsoft/fast-element/-/fast-element-1.13.0.tgz#d390ff13697064a48dc6ad6bb332a5f5489f73f8" - integrity sha512-iFhzKbbD0cFRo9cEzLS3Tdo9BYuatdxmCEKCpZs1Cro/93zNMpZ/Y9/Z7SknmW6fhDZbpBvtO8lLh9TFEcNVAQ== +"@microsoft/fast-element@^2.0.0-beta.17": + version "2.0.0-beta.17" + resolved "https://registry.yarnpkg.com/@microsoft/fast-element/-/fast-element-2.0.0-beta.17.tgz#46f9b1feaf57e0cb841d31a80574537257b2239f" + integrity sha512-R9NLnH0rh/btfBIdDicHGblw4uk4U7TNTnfpZ25W5IC52cWg7DLr0ky5GujH7wXge8F4ze/Z8anABzhC9eHYrA== -"@microsoft/fast-foundation@^2.49.6": - version "2.49.6" - resolved "https://registry.yarnpkg.com/@microsoft/fast-foundation/-/fast-foundation-2.49.6.tgz#0bdee7d28dcf93918075618359b083a676d2891c" - integrity sha512-DZVr+J/NIoskFC1Y6xnAowrMkdbf2d5o7UyWK6gW5AiQ6S386Ql8dw4KcC4kHaeE1yL2CKvweE79cj6ZhJhTvA== +"@microsoft/fast-foundation@^3.0.0-alpha.21": + version "3.0.0-alpha.21" + resolved "https://registry.yarnpkg.com/@microsoft/fast-foundation/-/fast-foundation-3.0.0-alpha.21.tgz#b867b3483d9e2ed496b301e6a6c4017adfa333f4" + integrity sha512-hKY2aI7OI54SN+h2ayJVh4CLD8dcbCuaOWihdiUTBnwNVgl/xANazO3q+Cs2P/5gHHOy2lIgJOZvsK9ilBsCQQ== dependencies: - "@microsoft/fast-element" "^1.13.0" - "@microsoft/fast-web-utilities" "^5.4.1" + "@floating-ui/dom" "^1.0.3" + "@microsoft/fast-element" "^2.0.0-beta.17" + "@microsoft/fast-web-utilities" "^6.0.0" tabbable "^5.2.0" - tslib "^1.13.0" + tslib "^2.4.0" -"@microsoft/fast-web-utilities@^5.4.0", "@microsoft/fast-web-utilities@^5.4.1": - version "5.4.1" - resolved "https://registry.yarnpkg.com/@microsoft/fast-web-utilities/-/fast-web-utilities-5.4.1.tgz#8e3082ee2ff2b5467f17e7cb1fb01b0e4906b71f" - integrity sha512-ReWYncndjV3c8D8iq9tp7NcFNc1vbVHvcBFPME2nNFKNbS1XCesYZGlIlf3ot5EmuOXPlrzUHOWzQ2vFpIkqDg== +"@microsoft/fast-web-utilities@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@microsoft/fast-web-utilities/-/fast-web-utilities-6.0.0.tgz#7678c2b2cd12aeef785f4e2288da93a4db9e38a6" + integrity sha512-ckCA4Xn91ja1Qz+jhGGL1Q3ZeuRpA5VvYcRA7GzA1NP545sl14bwz3tbHCq8jIk+PL7mkSaIveGMYuJB2L4Izg== dependencies: exenv-es6 "^1.1.1" @@ -23055,7 +23058,7 @@ tsconfig-paths@^3.12.0, tsconfig-paths@^3.9.0: minimist "^1.2.0" strip-bom "^3.0.0" -tslib@1.11.2: +tslib@1.11.2, tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.11.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.2.tgz#9c79d83272c9a7aaf166f73915c9667ecdde3cc9" integrity sha512-tTSkux6IGPnUGUd1XAZHcpu85MOkIl5zX49pO+jfsie3eP0B6pyhOlLXm3cAC6T7s+euSDDUUV+Acop5WmtkVg== @@ -23065,11 +23068,6 @@ tslib@2.5.0, tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.2. resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== -tslib@^1.10.0, tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - tsutils@^3.0.0, tsutils@^3.17.1, tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" From 49b1287dbaceafff494feac8744f3ba564cba66e Mon Sep 17 00:00:00 2001 From: Martin Hochel Date: Wed, 11 Jan 2023 19:13:31 +0100 Subject: [PATCH 006/203] chore: setup typescript 4.7 for web-components package (#26299) * chore: setup typescript 4.7 for web-components package * chore: generate change-file * fixup! chore: setup typescript 4.7 for web-components package * fixup! fixup! chore: setup typescript 4.7 for web-components package --- ...-974b7e3c-cb82-4399-8daf-f58a9a1b23ed.json | 7 +++ package.json | 6 +- packages/web-components/.eslintrc.js | 57 ----------------- packages/web-components/.eslintrc.json | 62 +++++++++++++++++++ packages/web-components/.storybook/main.js | 33 +++++++--- packages/web-components/.storybook/manager.js | 2 +- .../.storybook/{preview.js => preview.mjs} | 6 +- .../.storybook/{theme.js => theme.mjs} | 0 .../{karma.conf.js => karma.conf.cjs} | 2 +- packages/web-components/package.json | 25 +++++--- packages/web-components/rollup.config.js | 5 ++ .../{setup-browser.ts => setup-browser.cts} | 0 yarn.lock | 8 +-- 13 files changed, 126 insertions(+), 87 deletions(-) create mode 100644 change/@fluentui-web-components-974b7e3c-cb82-4399-8daf-f58a9a1b23ed.json delete mode 100644 packages/web-components/.eslintrc.js create mode 100644 packages/web-components/.eslintrc.json rename packages/web-components/.storybook/{preview.js => preview.mjs} (78%) rename packages/web-components/.storybook/{theme.js => theme.mjs} (100%) rename packages/web-components/{karma.conf.js => karma.conf.cjs} (98%) rename packages/web-components/src/__test__/{setup-browser.ts => setup-browser.cts} (100%) diff --git a/change/@fluentui-web-components-974b7e3c-cb82-4399-8daf-f58a9a1b23ed.json b/change/@fluentui-web-components-974b7e3c-cb82-4399-8daf-f58a9a1b23ed.json new file mode 100644 index 0000000000000..9581a88f06183 --- /dev/null +++ b/change/@fluentui-web-components-974b7e3c-cb82-4399-8daf-f58a9a1b23ed.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: setup typescript 4.7 for web-components package", + "packageName": "@fluentui/web-components", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/package.json b/package.json index c341bd79c3662..6e86adc0dc321 100644 --- a/package.json +++ b/package.json @@ -326,7 +326,7 @@ "through2": "4.0.2", "tmp": "0.2.1", "ts-jest": "29.1.1", - "ts-loader": "9.3.1", + "ts-loader": "9.4.2", "ts-node": "10.9.1", "tsconfig-paths": "4.2.0", "tsconfig-paths-webpack-plugin": "4.1.0", @@ -362,7 +362,9 @@ "typings" ], "nohoist": [ - "@fluentui/web-components/@storybook/html" + "@fluentui/web-components/@storybook/html", + "@fluentui/web-components/@microsoft/api-extractor", + "@fluentui/web-components/@microsoft/api-extractor/**" ] }, "resolutions": { diff --git a/packages/web-components/.eslintrc.js b/packages/web-components/.eslintrc.js deleted file mode 100644 index d3118d7db8188..0000000000000 --- a/packages/web-components/.eslintrc.js +++ /dev/null @@ -1,57 +0,0 @@ -module.exports = { - root: true, - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint', 'import'], - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/eslint-recommended', - 'plugin:@typescript-eslint/recommended', - 'prettier', - ], - settings: { - react: { - version: 'latest', - }, - }, - rules: { - 'no-extra-boolean-cast': 'off', - 'no-prototype-builtins': 'off', - 'no-fallthrough': 'off', - 'no-unexpected-multiline': 'off', - 'import/order': 'error', - 'sort-imports': [ - 'error', - { - ignoreCase: true, - ignoreDeclarationSort: true, - }, - ], - 'comma-dangle': 'off', - '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/no-use-before-define': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/camelcase': 'off', - '@typescript-eslint/no-inferrable-types': 'off', - '@typescript-eslint/no-unused-vars': ['warn', { args: 'none' }], - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/naming-convention': [ - 'error', - { - selector: 'default', - format: ['UPPER_CASE', 'camelCase', 'PascalCase'], - leadingUnderscore: 'allow', - }, - { - selector: 'property', - format: null, // disable for property names because of our foo__expanded convention for JSS - // TODO: I think we can come up with a regex that ignores variables with __ in them - }, - { - selector: 'variable', - format: null, // disable for variable names because of our foo__expanded convention for JSS - // TODO: I think we can come up with a regex that ignores variables with __ in them - }, - ], - }, -}; diff --git a/packages/web-components/.eslintrc.json b/packages/web-components/.eslintrc.json new file mode 100644 index 0000000000000..ca5b46cb7c91c --- /dev/null +++ b/packages/web-components/.eslintrc.json @@ -0,0 +1,62 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint", "import"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "prettier" + ], + "settings": { + "react": { + "version": "latest" + } + }, + "rules": { + "no-extra-boolean-cast": "off", + "no-prototype-builtins": "off", + "no-fallthrough": "off", + "no-unexpected-multiline": "off", + "import/order": "error", + "sort-imports": [ + "error", + { + "ignoreCase": true, + "ignoreDeclarationSort": true + } + ], + "comma-dangle": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-use-before-define": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/camelcase": "off", + "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/no-unused-vars": [ + "warn", + { + "args": "none" + } + ], + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/naming-convention": [ + "error", + { + "selector": "default", + "format": ["UPPER_CASE", "camelCase", "PascalCase"], + "leadingUnderscore": "allow" + }, + { + "selector": "property", + "format": null // disable for property names because of our foo__expanded convention for JSS + // TODO: I think we can come up with a regex that ignores variables with __ in them + }, + { + "selector": "variable", + "format": null // disable for variable names because of our foo__expanded convention for JSS + // TODO: I think we can come up with a regex that ignores variables with __ in them + } + ] + } +} diff --git a/packages/web-components/.storybook/main.js b/packages/web-components/.storybook/main.js index 352a8ec7d0084..e42bb815bb8d9 100644 --- a/packages/web-components/.storybook/main.js +++ b/packages/web-components/.storybook/main.js @@ -1,5 +1,7 @@ const CircularDependencyPlugin = require('circular-dependency-plugin'); +const tsBin = require.resolve('typescript'); + module.exports = { stories: ['../src/**/*.stories.@(ts|mdx)'], staticDirs: ['../public'], @@ -22,16 +24,29 @@ module.exports = { }, ], webpackFinal: async config => { - config.module.rules.push({ - test: /\.ts$/, - use: [ - { - loader: 'ts-loader', + config.resolve.extensionAlias = { + '.js': ['.ts', '.js'], + '.mjs': ['.mts', '.mjs'], + }; + config.module.rules.push( + { + test: /\.([cm]?ts|tsx)$/, + loader: 'ts-loader', + sideEffects: true, + options: { + transpileOnly: true, + compiler: tsBin, }, - ], - }); - config.resolve.extensions.push('.ts'); - config.resolve.extensions.push('.js'); + }, + // Following config is needed to be able to resolve @storybook packages imported in specified files that don't ship valid ESM + // It also enables importing other packages without proper ESM extensions, but that should be avoided ! + // @see https://webpack.js.org/configuration/module/#resolvefullyspecified + { + test: /\.storybook\/.+\.m?js/, + resolve: { fullySpecified: false }, + }, + ); + config.resolve.extensions.push(...['.ts', '.js']); config.plugins.push( new CircularDependencyPlugin({ exclude: /node_modules/, diff --git a/packages/web-components/.storybook/manager.js b/packages/web-components/.storybook/manager.js index a46a132161789..5dcaa431bdecd 100644 --- a/packages/web-components/.storybook/manager.js +++ b/packages/web-components/.storybook/manager.js @@ -1,5 +1,5 @@ import { addons } from '@storybook/addons'; -import webcomponentsTheme from './theme'; +import webcomponentsTheme from './theme.mjs'; addons.setConfig({ previewTabs: { diff --git a/packages/web-components/.storybook/preview.js b/packages/web-components/.storybook/preview.mjs similarity index 78% rename from packages/web-components/.storybook/preview.js rename to packages/web-components/.storybook/preview.mjs index c1340a5c49bde..3fb4a4e08285c 100644 --- a/packages/web-components/.storybook/preview.js +++ b/packages/web-components/.storybook/preview.mjs @@ -1,6 +1,6 @@ -import * as Fluent from '../src/index-rollup'; -import webcomponentsTheme from './theme'; -import { switchTheme } from '../public/theme-switch'; +import * as Fluent from '../src/index-rollup.ts'; +import webcomponentsTheme from './theme.mjs'; +import { switchTheme } from '../public/theme-switch.ts'; Fluent; diff --git a/packages/web-components/.storybook/theme.js b/packages/web-components/.storybook/theme.mjs similarity index 100% rename from packages/web-components/.storybook/theme.js rename to packages/web-components/.storybook/theme.mjs diff --git a/packages/web-components/karma.conf.js b/packages/web-components/karma.conf.cjs similarity index 98% rename from packages/web-components/karma.conf.js rename to packages/web-components/karma.conf.cjs index 71091978d65ac..50321485c4632 100644 --- a/packages/web-components/karma.conf.js +++ b/packages/web-components/karma.conf.cjs @@ -46,7 +46,7 @@ module.exports = function (config) { ], files: [`dist/esm/__test__/${setup}.js`], preprocessors: { - [`dist/esm/__test__/${setup}.js`]: ['webpack', 'sourcemap'], + [`dist/esm/__test__/${setup}.cjs`]: ['webpack', 'sourcemap'], }, webpackMiddleware: { // webpack-dev-middleware configuration diff --git a/packages/web-components/package.json b/packages/web-components/package.json index e59096943dae0..c9ed5bf4e8df6 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -15,13 +15,16 @@ "bugs": { "url": "https://github.com/Microsoft/fluentui/issues/new/choose" }, + "type": "module", "main": "dist/esm/index.js", "types": "dist/web-components.d.ts", "unpkg": "dist/web-components.min.js", "scripts": { + "tsc": "tsc", + "api-extractor": "api-extractor", "clean": "node ./build/clean.js dist", "doc": "api-extractor run --local", - "doc:ci": "api-extractor run --local", + "doc:ci": "yarn doc", "build": "tsc -p ./tsconfig.json && rollup -c && yarn doc", "dev": "tsc -p ./tsconfig.json -w", "tdd": "yarn dev & yarn test-chrome:watch", @@ -37,14 +40,14 @@ "test": "yarn doc:ci && yarn test-chrome:verbose", "test-node": "mocha --reporter min --exit dist/esm/__test__/setup-node.js './dist/esm/**/*.spec.js'", "test-node:verbose": "mocha --reporter spec --exit dist/esm/__test__/setup-node.js './dist/esm/**/*.spec.js'", - "test-chrome": "karma start karma.conf.js --browsers=ChromeHeadlessOpt --single-run --coverage", - "test-chrome:verbose": "karma start karma.conf.js --browsers=ChromeHeadlessOpt --single-run --coverage --reporter=mocha", - "test-chrome:watch": "karma start karma.conf.js --browsers=ChromeHeadlessOpt --coverage --watch-extensions js", - "test-chrome:debugger": "karma start karma.conf.js --browsers=ChromeDebugging", - "test-chrome:verbose:watch": "karma start karma.conf.js --browsers=ChromeHeadlessOpt --coverage --watch-extensions js --reporter=mocha ", - "test-chrome:verbose:debugger": "karma start karma.conf.js --browsers=ChromeDebugging --reporter=mocha", - "test-firefox": "karma start karma.conf.js --browsers=FirefoxHeadless --single-run --coverage", - "test-firefox:verbose": "karma start karma.conf.js --browsers=FirefoxHeadless --single-run --coverage --reporter=mocha" + "test-chrome": "karma start karma.conf.cjs --browsers=ChromeHeadlessOpt --single-run --coverage", + "test-chrome:verbose": "karma start karma.conf.cjs --no-fail-on-empty-test-suite --browsers=ChromeHeadlessOpt --single-run --coverage --reporter=mocha", + "test-chrome:watch": "karma start karma.conf.cjs --browsers=ChromeHeadlessOpt --coverage --watch-extensions js", + "test-chrome:debugger": "karma start karma.conf.cjs --browsers=ChromeDebugging", + "test-chrome:verbose:watch": "karma start karma.conf.cjs --browsers=ChromeHeadlessOpt --coverage --watch-extensions js --reporter=mocha ", + "test-chrome:verbose:debugger": "karma start karma.conf.cjs --browsers=ChromeDebugging --reporter=mocha", + "test-firefox": "karma start karma.conf.cjs --browsers=FirefoxHeadless --single-run --coverage", + "test-firefox:verbose": "karma start karma.conf.cjs --browsers=FirefoxHeadless --single-run --coverage --reporter=mocha" }, "devDependencies": { "@storybook/html": "6.5.15", @@ -69,7 +72,9 @@ "karma-source-map-support": "1.4.0", "karma-sourcemap-loader": "0.3.8", "karma-webpack": "5.0.0", - "mocha": "7.2.0" + "mocha": "7.2.0", + "@microsoft/api-extractor": "7.31.2", + "typescript": "4.7.4" }, "dependencies": { "@microsoft/fast-element": "^2.0.0-beta.17", diff --git a/packages/web-components/rollup.config.js b/packages/web-components/rollup.config.js index c79ffeb292333..d3c02fd5ba91c 100644 --- a/packages/web-components/rollup.config.js +++ b/packages/web-components/rollup.config.js @@ -6,6 +6,9 @@ import transformTaggedTemplate from 'rollup-plugin-transform-tagged-template'; import typescript from 'rollup-plugin-typescript2'; import { transformCSSFragment, transformHTMLFragment } from './build/transform-fragments'; +// eslint-disable-next-line no-undef +const tsBin = require.resolve('typescript'); + const parserOptions = { sourceType: 'module', }; @@ -28,6 +31,8 @@ export default [ resolve(), commonJS(), typescript({ + // eslint-disable-next-line no-undef + typescript: require(tsBin), tsconfigOverride: { compilerOptions: { declaration: false, diff --git a/packages/web-components/src/__test__/setup-browser.ts b/packages/web-components/src/__test__/setup-browser.cts similarity index 100% rename from packages/web-components/src/__test__/setup-browser.ts rename to packages/web-components/src/__test__/setup-browser.cts diff --git a/yarn.lock b/yarn.lock index ceed30e4e4c46..64ac5a9b24b39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22982,10 +22982,10 @@ ts-jest@29.1.1: semver "^7.5.3" yargs-parser "^21.0.1" -ts-loader@9.3.1: - version "9.3.1" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.3.1.tgz#fe25cca56e3e71c1087fe48dc67f4df8c59b22d4" - integrity sha512-OkyShkcZTsTwyS3Kt7a4rsT/t2qvEVQuKCTg4LJmpj9fhFR7ukGdZwV6Qq3tRUkqcXtfGpPR7+hFKHCG/0d3Lw== +ts-loader@9.4.2: + version "9.4.2" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.4.2.tgz#80a45eee92dd5170b900b3d00abcfa14949aeb78" + integrity sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA== dependencies: chalk "^4.1.0" enhanced-resolve "^5.0.0" From 1432e12236b3accb1c7310f30a440ef9245524a5 Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Wed, 11 Jan 2023 16:54:30 -0800 Subject: [PATCH 007/203] feat: add text as new component (#26090) * add text as a new component * update main.js to .cjs format for esm due to require syntax * update style rules to align with FUI react v9, export text options, update stories to leverage object.keys of options * export text, update node resolution to 16 and fix object.keys for size to object.values * prettier style files, may need to revert if it does not play nice with selectors * update display for host to ensure we can layout the element properly margin, etc... * update latest FAST packages * leverage ValuesOf type helper --- .prettierignore | 1 - ...-06188225-69da-4cf6-918c-932a9ceab1b3.json | 7 + .../.storybook/{main.js => main.cjs} | 0 packages/web-components/docs/api-report.md | 82 ++++++++++- packages/web-components/package.json | 14 +- .../web-components/src/__test__/helpers.ts | 56 ++++++++ .../src/fluent-design-system.ts | 5 + packages/web-components/src/index-rollup.ts | 2 +- packages/web-components/src/index.ts | 2 +- packages/web-components/src/text/define.ts | 4 + packages/web-components/src/text/index.ts | 5 + .../src/text/text.definition.ts | 18 +++ .../web-components/src/text/text.options.ts | 75 ++++++++++ .../web-components/src/text/text.stories.ts | 120 ++++++++++++++++ .../web-components/src/text/text.styles.ts | 133 ++++++++++++++++++ .../web-components/src/text/text.template.ts | 7 + packages/web-components/src/text/text.ts | 111 +++++++++++++++ packages/web-components/src/theme/index.ts | 4 +- .../web-components/src/theme/set-theme.ts | 2 +- .../web-components/src/theme/theme.stories.ts | 2 +- packages/web-components/tsconfig.json | 2 +- yarn.lock | 18 +-- 22 files changed, 649 insertions(+), 21 deletions(-) create mode 100644 change/@fluentui-web-components-06188225-69da-4cf6-918c-932a9ceab1b3.json rename packages/web-components/.storybook/{main.js => main.cjs} (100%) create mode 100644 packages/web-components/src/__test__/helpers.ts create mode 100644 packages/web-components/src/fluent-design-system.ts create mode 100644 packages/web-components/src/text/define.ts create mode 100644 packages/web-components/src/text/index.ts create mode 100644 packages/web-components/src/text/text.definition.ts create mode 100644 packages/web-components/src/text/text.options.ts create mode 100644 packages/web-components/src/text/text.stories.ts create mode 100644 packages/web-components/src/text/text.styles.ts create mode 100644 packages/web-components/src/text/text.template.ts create mode 100644 packages/web-components/src/text/text.ts diff --git a/.prettierignore b/.prettierignore index 095b5614af383..030b7cab28754 100644 --- a/.prettierignore +++ b/.prettierignore @@ -35,7 +35,6 @@ packages/fluentui/docs/src/behaviorMenu.json packages/fluentui/docs/src/exampleMenus packages/fluentui/docs/src/exampleSources packages/fluentui/ability-attributes/src/schema.ts -packages/web-components/src/**/*.styles.ts packages/web-components/**/*.spec.ts packages/web-components/src/default-palette.ts diff --git a/change/@fluentui-web-components-06188225-69da-4cf6-918c-932a9ceab1b3.json b/change/@fluentui-web-components-06188225-69da-4cf6-918c-932a9ceab1b3.json new file mode 100644 index 0000000000000..4e872c1571b2d --- /dev/null +++ b/change/@fluentui-web-components-06188225-69da-4cf6-918c-932a9ceab1b3.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "add text as a new component", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/.storybook/main.js b/packages/web-components/.storybook/main.cjs similarity index 100% rename from packages/web-components/.storybook/main.js rename to packages/web-components/.storybook/main.cjs diff --git a/packages/web-components/docs/api-report.md b/packages/web-components/docs/api-report.md index 89e2eb718dbf1..c027d600e8202 100644 --- a/packages/web-components/docs/api-report.md +++ b/packages/web-components/docs/api-report.md @@ -4,8 +4,86 @@ ```ts -// @public (undocumented) -export const empty = ""; +import { ElementStyles } from '@microsoft/fast-element'; +import { ElementViewTemplate } from '@microsoft/fast-element'; +import { FASTElement } from '@microsoft/fast-element'; +import { FASTElementDefinition } from '@microsoft/fast-element'; +import { ValuesOf } from '@microsoft/fast-foundation'; + +// @public +class Text_2 extends FASTElement { + align: TextAlign; + block: boolean; + font: TextFont; + italic: boolean; + nowrap: boolean; + size: TextSize; + strikethrough: boolean; + truncate: boolean; + underline: boolean; + weight: TextWeight; +} +export { Text_2 as Text } + +// @public +export const TextAlign: { + readonly start: "start"; + readonly end: "end"; + readonly center: "center"; + readonly justify: "justify"; +}; + +// @public +export type TextAlign = ValuesOf; + +// @public +export const TextDefinition: FASTElementDefinition; + +// @public +export const TextFont: { + readonly base: "base"; + readonly numeric: "numeric"; + readonly monospace: "monospace"; +}; + +// @public +export type TextFont = ValuesOf; + +// @public +export const TextSize: { + readonly _100: "100"; + readonly _200: "200"; + readonly _300: "300"; + readonly _400: "400"; + readonly _500: "500"; + readonly _600: "600"; + readonly _700: "700"; + readonly _800: "800"; + readonly _900: "900"; + readonly _1000: "1000"; +}; + +// @public +export type TextSize = ValuesOf; + +// @public +export const TextStyles: ElementStyles; + +// Warning: (ae-internal-missing-underscore) The name "TextTemplate" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal (undocumented) +export const TextTemplate: ElementViewTemplate; + +// @public +export const TextWeight: { + readonly medium: "medium"; + readonly regular: "regular"; + readonly semibold: "semibold"; + readonly bold: "bold"; +}; + +// @public +export type TextWeight = ValuesOf; // (No @packageDocumentation comment for this package) diff --git a/packages/web-components/package.json b/packages/web-components/package.json index c9ed5bf4e8df6..3bed54f6654c0 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -19,6 +19,16 @@ "main": "dist/esm/index.js", "types": "dist/web-components.d.ts", "unpkg": "dist/web-components.min.js", + "exports": { + ".": { + "types": "./dist/dts/index.d.ts", + "default": "./dist/esm/index.js" + }, + "./text": { + "types": "./dist/esm/text/define.d.ts", + "default": "./dist/esm/text/define.js" + } + }, "scripts": { "tsc": "tsc", "api-extractor": "api-extractor", @@ -77,8 +87,8 @@ "typescript": "4.7.4" }, "dependencies": { - "@microsoft/fast-element": "^2.0.0-beta.17", - "@microsoft/fast-foundation": "^3.0.0-alpha.21", + "@microsoft/fast-element": "^2.0.0-beta.20", + "@microsoft/fast-foundation": "^3.0.0-alpha.24", "@microsoft/fast-web-utilities": "^6.0.0", "@fluentui/tokens": "1.0.0-alpha.2", "tslib": "^2.1.0" diff --git a/packages/web-components/src/__test__/helpers.ts b/packages/web-components/src/__test__/helpers.ts new file mode 100644 index 0000000000000..5bdf603f031f9 --- /dev/null +++ b/packages/web-components/src/__test__/helpers.ts @@ -0,0 +1,56 @@ +import type { FASTElement, ViewTemplate } from '@microsoft/fast-element'; +import type { AnnotatedStoryFn, Args, ComponentAnnotations, StoryAnnotations } from '@storybook/csf'; + +/** + * A helper that returns a function to bind a Storybook story to a ViewTemplate. + * + * @param template - The ViewTemplate to render + * @returns - a function to bind a Storybook story + */ +export function renderComponent( + template: ViewTemplate, +): (args: TArgs) => Element | DocumentFragment | null { + return function (args) { + const storyFragment = new DocumentFragment(); + template.render(args, storyFragment); + if (storyFragment.childElementCount === 1) { + return storyFragment.firstElementChild; + } + return storyFragment; + }; +} + +/** + * A helper that returns a function to bind a Storybook story to a ViewTemplate. + */ +export type FASTFramework = { + component: typeof FASTElement; + storyResult: FASTElement | Element | DocumentFragment; +}; + +/** + * Metadata to configure the stories for a component. + */ +export type Meta = ComponentAnnotations>; + +/** + * Story function that represents a CSFv3 component example. + */ +export declare type StoryObj = StoryAnnotations; + +/** + * Story function that represents a CSFv2 component example. + */ +export declare type StoryFn = AnnotatedStoryFn; + +/** + * Story function that represents a CSFv2 component example. + * + * NOTE that in Storybook 7.0, this type will be renamed to `StoryFn` and replaced by the current `StoryObj` type. + */ +export declare type Story = StoryFn>; + +/** + * Combined Storybook story args. + */ +export type StoryArgs = Partial> & Args; diff --git a/packages/web-components/src/fluent-design-system.ts b/packages/web-components/src/fluent-design-system.ts new file mode 100644 index 0000000000000..293d22781974e --- /dev/null +++ b/packages/web-components/src/fluent-design-system.ts @@ -0,0 +1,5 @@ +export const FluentDesignSystem = Object.freeze({ + prefix: 'fluent', + shadowRootMode: 'open', + registry: customElements, +}); diff --git a/packages/web-components/src/index-rollup.ts b/packages/web-components/src/index-rollup.ts index ea465c2a34a4e..ee01cc9bd3233 100644 --- a/packages/web-components/src/index-rollup.ts +++ b/packages/web-components/src/index-rollup.ts @@ -1 +1 @@ -export * from './index'; +export * from './index.js'; diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index 7d394c507ef22..dd622fd56e566 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -1 +1 @@ -export const empty = ''; +export * from './text/index.js'; diff --git a/packages/web-components/src/text/define.ts b/packages/web-components/src/text/define.ts new file mode 100644 index 0000000000000..5d11371ac5fca --- /dev/null +++ b/packages/web-components/src/text/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './text.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/text/index.ts b/packages/web-components/src/text/index.ts new file mode 100644 index 0000000000000..663cf3ebbf645 --- /dev/null +++ b/packages/web-components/src/text/index.ts @@ -0,0 +1,5 @@ +export * from './text.js'; +export * from './text.options.js'; +export { template as TextTemplate } from './text.template.js'; +export { styles as TextStyles } from './text.styles.js'; +export { definition as TextDefinition } from './text.definition.js'; diff --git a/packages/web-components/src/text/text.definition.ts b/packages/web-components/src/text/text.definition.ts new file mode 100644 index 0000000000000..02bb15599612d --- /dev/null +++ b/packages/web-components/src/text/text.definition.ts @@ -0,0 +1,18 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Text } from './text.js'; +import { styles } from './text.styles.js'; +import { template } from './text.template.js'; + +/** + * The Fluent Text Element. + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = Text.compose({ + name: `${FluentDesignSystem.prefix}-text`, + template, + styles, +}); diff --git a/packages/web-components/src/text/text.options.ts b/packages/web-components/src/text/text.options.ts new file mode 100644 index 0000000000000..0c775c78b2ddd --- /dev/null +++ b/packages/web-components/src/text/text.options.ts @@ -0,0 +1,75 @@ +import { ValuesOf } from '@microsoft/fast-foundation'; + +/** + * TextSize constants + * @public + */ +export const TextSize = { + _100: '100', + _200: '200', + _300: '300', + _400: '400', + _500: '500', + _600: '600', + _700: '700', + _800: '800', + _900: '900', + _1000: '1000', +} as const; + +/** + * The type for TextSize + * The font size and line height based on the theme tokens + * @public + */ +export type TextSize = ValuesOf; + +/** + * TextFont Constants + * @public + */ +export const TextFont = { + base: 'base', + numeric: 'numeric', + monospace: 'monospace', +} as const; + +/** + * Applies font family to the content + * @public + */ +export type TextFont = ValuesOf; + +/** + * TextWeight Constants + * @public + */ +export const TextWeight = { + medium: 'medium', + regular: 'regular', + semibold: 'semibold', + bold: 'bold', +} as const; + +/** + * Applies font weight to the content + * @public + */ +export type TextWeight = ValuesOf; + +/** + * TextAlign Constants + * @public + */ +export const TextAlign = { + start: 'start', + end: 'end', + center: 'center', + justify: 'justify', +} as const; + +/** + * Aligns the content + * @public + */ +export type TextAlign = ValuesOf; diff --git a/packages/web-components/src/text/text.stories.ts b/packages/web-components/src/text/text.stories.ts new file mode 100644 index 0000000000000..511c274062484 --- /dev/null +++ b/packages/web-components/src/text/text.stories.ts @@ -0,0 +1,120 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../__test__/helpers.js'; +import type { Text as FluentText } from './text.js'; +import './define.js'; +import { TextAlign, TextFont, TextSize, TextWeight } from './text.options.js'; + +type TextStoryArgs = Args & FluentText; +type TextStoryMeta = Meta; + +/** + * Used to generate slotted content for stories + * @param as - the element to generate + * @param content - the content for the element + * @returns ViewTemplate + */ +const generateSemanticElementTemplate = (as: string, content) => { + switch (as) { + case 'h1': + return html`

${content}

`; + case 'h2': + return html`

${content}

`; + case 'h3': + return html`

${content}

`; + case 'h4': + return html`

${content}

`; + case 'h5': + return html`
${content}
`; + case 'h6': + return html`
${content}
`; + case 'p': + return html`

${content}

`; + case 'pre': + return html`
${content}
`; + case 'span': + default: + return html`${content}`; + } +}; + +const storyTemplate = html` + x.align} + font=${x => x.font} + size=${x => x.size} + weight=${x => x.weight} + ?nowrap=${x => x.nowrap} + ?truncate=${x => x.truncate} + ?italic=${x => x.italic} + ?underline=${x => x.underline} + ?strikethrough=${x => x.strikethrough} + ?block=${x => x.block} + >${x => generateSemanticElementTemplate(x.as, x.content)} +`; + +export default { + title: 'Components/Text', + args: { + content: 'Text', + nowrap: false, + truncate: false, + italic: false, + underline: false, + strikethrough: false, + block: false, + }, + argTypes: { + as: { + options: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'pre', 'span'], + control: { + type: 'select', + }, + }, + size: { + options: Object.values(TextSize), + control: { + type: 'select', + }, + }, + weight: { + options: Object.keys(TextWeight), + control: { + type: 'select', + }, + }, + align: { + options: Object.keys(TextAlign), + control: { + type: 'select', + }, + }, + font: { + options: Object.keys(TextFont), + control: { + type: 'select', + }, + }, + nowrap: { + control: 'boolean', + }, + truncate: { + control: 'boolean', + }, + italic: { + control: 'boolean', + }, + underline: { + control: 'boolean', + }, + strikethrough: { + control: 'boolean', + }, + block: { + control: 'boolean', + }, + }, +} as TextStoryMeta; + +export const Text = renderComponent(storyTemplate).bind({}); diff --git a/packages/web-components/src/text/text.styles.ts b/packages/web-components/src/text/text.styles.ts new file mode 100644 index 0000000000000..cfe208b822005 --- /dev/null +++ b/packages/web-components/src/text/text.styles.ts @@ -0,0 +1,133 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + fontFamilyBase, + fontFamilyMonospace, + fontFamilyNumeric, + fontSizeBase100, + fontSizeBase200, + fontSizeBase300, + fontSizeBase400, + fontSizeBase500, + fontSizeBase600, + fontSizeHero1000, + fontSizeHero700, + fontSizeHero800, + fontSizeHero900, + fontWeightBold, + fontWeightMedium, + fontWeightRegular, + fontWeightSemibold, + lineHeightBase100, + lineHeightBase200, + lineHeightBase300, + lineHeightBase400, + lineHeightBase500, + lineHeightBase600, + lineHeightHero1000, + lineHeightHero700, + lineHeightHero800, + lineHeightHero900, +} from '../theme/design-tokens.js'; + +/** Text styles + * @public + */ +export const styles = css` + ${display('inline')} + + ::slotted(*) { + font-family: ${fontFamilyBase}; + font-size: ${fontSizeBase300}; + line-height: ${lineHeightBase300}; + font-weight: ${fontWeightRegular}; + text-align: start; + display: inline; + white-space: normal; + overflow: visible; + text-overflow: clip; + margin: 0; + } + :host([nowrap]) ::slotted(*) { + white-space: nowrap; + overflow: hidden; + } + :host([truncate]) ::slotted(*) { + text-overflow: ellipsis; + } + :host([block]) ::slotted(*) { + display: block; + } + :host([italic]) ::slotted(*) { + font-style: italic; + } + :host([underline]) ::slotted(*) { + text-decoration-line: underline; + } + :host([strikethrough]) ::slotted(*) { + text-decoration-line: line-through; + } + :host([underline][strikethrough]) ::slotted(*) { + text-decoration-line: line-through underline; + } + :host([size='100']) ::slotted(*) { + font-size: ${fontSizeBase100}; + line-height: ${lineHeightBase100}; + } + :host([size='200']) ::slotted(*) { + font-size: ${fontSizeBase200}; + line-height: ${lineHeightBase200}; + } + :host([size='400']) ::slotted(*) { + font-size: ${fontSizeBase400}; + line-height: ${lineHeightBase400}; + } + :host([size='500']) ::slotted(*) { + font-size: ${fontSizeBase500}; + line-height: ${lineHeightBase500}; + } + :host([size='600']) ::slotted(*) { + font-size: ${fontSizeBase600}; + line-height: ${lineHeightBase600}; + } + :host([size='700']) ::slotted(*) { + font-size: ${fontSizeHero700}; + line-height: ${lineHeightHero700}; + } + :host([size='800']) ::slotted(*) { + font-size: ${fontSizeHero800}; + line-height: ${lineHeightHero800}; + } + :host([size='900']) ::slotted(*) { + font-size: ${fontSizeHero900}; + line-height: ${lineHeightHero900}; + } + :host([size='1000']) ::slotted(*) { + font-size: ${fontSizeHero1000}; + line-height: ${lineHeightHero1000}; + } + :host([font='monospace']) ::slotted(*) { + font-family: ${fontFamilyMonospace}; + } + :host([font='numeric']) ::slotted(*) { + font-family: ${fontFamilyNumeric}; + } + :host([weight='medium']) ::slotted(*) { + font-weight: ${fontWeightMedium}; + } + :host([weight='semibold']) ::slotted(*) { + font-weight: ${fontWeightSemibold}; + } + :host([weight='bold']) ::slotted(*) { + font-weight: ${fontWeightBold}; + } + :host([align='center']) ::slotted(*) { + text-align: center; + } + :host([align='end']) ::slotted(*) { + text-align: end; + } + :host([align='justify']) ::slotted(*) { + text-align: justify; + } +`; diff --git a/packages/web-components/src/text/text.template.ts b/packages/web-components/src/text/text.template.ts new file mode 100644 index 0000000000000..1498579181854 --- /dev/null +++ b/packages/web-components/src/text/text.template.ts @@ -0,0 +1,7 @@ +import { ElementViewTemplate, html } from '@microsoft/fast-element'; +import type { Text } from './text.js'; + +/** + * @internal + */ +export const template: ElementViewTemplate = html``; diff --git a/packages/web-components/src/text/text.ts b/packages/web-components/src/text/text.ts new file mode 100644 index 0000000000000..a666fb0950822 --- /dev/null +++ b/packages/web-components/src/text/text.ts @@ -0,0 +1,111 @@ +import { attr, FASTElement } from '@microsoft/fast-element'; +import type { TextAlign, TextFont, TextSize, TextWeight } from './text.options.js'; + +/** + * The base class used for constructing a fluent-text custom element + * @public + */ +export class Text extends FASTElement { + /** + * The text will not wrap + * NOTE: In Fluent UI React v9 this is "wrap" + * Boolean attributes which default to true in HTML can't be switched off in the DOM + * + * @public + * @remarks + * HTML Attribute: nowrap + */ + @attr({ mode: 'boolean' }) + nowrap: boolean = false; + + /** + * The text truncates + * + * @public + * @remarks + * HTML Attribute: truncate + */ + @attr({ mode: 'boolean' }) + truncate: boolean = false; + + /** + * The text style is italic + * + * @public + * @remarks + * HTML Attribute: italic + */ + @attr({ mode: 'boolean' }) + italic: boolean = false; + + /** + * The text style is underline + * + * @public + * @remarks + * HTML Attribute: underline + */ + @attr({ mode: 'boolean' }) + underline: boolean = false; + + /** + * The text style is strikethrough + * + * @public + * @remarks + * HTML Attribute: strikethrough + */ + @attr({ mode: 'boolean' }) + strikethrough: boolean = false; + + /** + * An text can take up the width of its container. + * + * @public + * @remarks + * HTML Attribute: block + */ + @attr({ mode: 'boolean' }) + block: boolean = false; + + /** + * THe Text size + * + * @public + * @remarks + * HTML Attribute: size + * + */ + @attr + size: TextSize; + + /** + * THe Text font + * + * @public + * @remarks + * HTML Attribute: font + */ + @attr + font: TextFont; + + /** + * THe Text weight + * + * @public + * @remarks + * HTML Attribute: weight + */ + @attr + weight: TextWeight; + + /** + * THe Text align + * + * @public + * @remarks + * HTML Attribute: align + */ + @attr + align: TextAlign; +} diff --git a/packages/web-components/src/theme/index.ts b/packages/web-components/src/theme/index.ts index 805ad62b80b66..28968493cd475 100644 --- a/packages/web-components/src/theme/index.ts +++ b/packages/web-components/src/theme/index.ts @@ -1,2 +1,2 @@ -export * from './design-tokens'; -export { setTheme } from './set-theme'; +export * from './design-tokens.js'; +export { setTheme } from './set-theme.js'; diff --git a/packages/web-components/src/theme/set-theme.ts b/packages/web-components/src/theme/set-theme.ts index 7c86f95ab2ac5..ea0aa8cd11065 100644 --- a/packages/web-components/src/theme/set-theme.ts +++ b/packages/web-components/src/theme/set-theme.ts @@ -1,5 +1,5 @@ import type { Theme } from '@fluentui/tokens'; -import * as tokens from './design-tokens'; +import * as tokens from './design-tokens.js'; const tokenNames = Object.keys(tokens); diff --git a/packages/web-components/src/theme/theme.stories.ts b/packages/web-components/src/theme/theme.stories.ts index 183987d06c461..63c78cb670fcd 100644 --- a/packages/web-components/src/theme/theme.stories.ts +++ b/packages/web-components/src/theme/theme.stories.ts @@ -1,5 +1,5 @@ import { DesignToken } from '@microsoft/fast-foundation'; -import * as tokens from '../theme/design-tokens'; +import * as tokens from '../theme/design-tokens.js'; DesignToken.registerDefaultStyleTarget(); diff --git a/packages/web-components/tsconfig.json b/packages/web-components/tsconfig.json index 1e252751d2e55..ec8a5a0595591 100644 --- a/packages/web-components/tsconfig.json +++ b/packages/web-components/tsconfig.json @@ -4,7 +4,7 @@ "esModuleInterop": true, "experimentalDecorators": true, "resolveJsonModule": true, - "moduleResolution": "node", + "moduleResolution": "Node16", "declarationDir": "dist/dts", "outDir": "dist/esm", "strictNullChecks": true, diff --git a/yarn.lock b/yarn.lock index 64ac5a9b24b39..c3a861c0b8484 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2657,18 +2657,18 @@ eslint-plugin-react "7.24.0" eslint-plugin-security "1.4.0" -"@microsoft/fast-element@^2.0.0-beta.17": - version "2.0.0-beta.17" - resolved "https://registry.yarnpkg.com/@microsoft/fast-element/-/fast-element-2.0.0-beta.17.tgz#46f9b1feaf57e0cb841d31a80574537257b2239f" - integrity sha512-R9NLnH0rh/btfBIdDicHGblw4uk4U7TNTnfpZ25W5IC52cWg7DLr0ky5GujH7wXge8F4ze/Z8anABzhC9eHYrA== +"@microsoft/fast-element@^2.0.0-beta.20": + version "2.0.0-beta.20" + resolved "https://registry.yarnpkg.com/@microsoft/fast-element/-/fast-element-2.0.0-beta.20.tgz#a8b145386fc2442c3dc60f2495f54b12cab85ef5" + integrity sha512-7Ehsq1FzLUQA90rQH14Bx6C0UAtx/13Ihm+0M7zQk46vL/PVvP0t/supn5UnjtI9d/zDrM5jxaFcxYjTfW8aIA== -"@microsoft/fast-foundation@^3.0.0-alpha.21": - version "3.0.0-alpha.21" - resolved "https://registry.yarnpkg.com/@microsoft/fast-foundation/-/fast-foundation-3.0.0-alpha.21.tgz#b867b3483d9e2ed496b301e6a6c4017adfa333f4" - integrity sha512-hKY2aI7OI54SN+h2ayJVh4CLD8dcbCuaOWihdiUTBnwNVgl/xANazO3q+Cs2P/5gHHOy2lIgJOZvsK9ilBsCQQ== +"@microsoft/fast-foundation@^3.0.0-alpha.24": + version "3.0.0-alpha.24" + resolved "https://registry.yarnpkg.com/@microsoft/fast-foundation/-/fast-foundation-3.0.0-alpha.24.tgz#3b750f1fbee9f7f9ca771053c7c941ff2d69fb6c" + integrity sha512-Ln33vUNm5t//rK0UAF/GM6njJr36M/ure0NUwbifAPqYmV8l9FgnnI+IY7kWBFhn+kZLERBh5sSz2TWGgMF9lg== dependencies: "@floating-ui/dom" "^1.0.3" - "@microsoft/fast-element" "^2.0.0-beta.17" + "@microsoft/fast-element" "^2.0.0-beta.20" "@microsoft/fast-web-utilities" "^6.0.0" tabbable "^5.2.0" tslib "^2.4.0" From 2e77479bb02ca5aa658937a6c25801839c5f9778 Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Fri, 13 Jan 2023 11:42:31 -0800 Subject: [PATCH 008/203] fix clean file and ensure rimraf is enumerated as dependency (#26350) --- ...eb-components-19128575-ce2e-40b1-8a3b-8334eb585f40.json | 7 +++++++ packages/web-components/build/{clean.js => clean.cjs} | 0 packages/web-components/package.json | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 change/@fluentui-web-components-19128575-ce2e-40b1-8a3b-8334eb585f40.json rename packages/web-components/build/{clean.js => clean.cjs} (100%) diff --git a/change/@fluentui-web-components-19128575-ce2e-40b1-8a3b-8334eb585f40.json b/change/@fluentui-web-components-19128575-ce2e-40b1-8a3b-8334eb585f40.json new file mode 100644 index 0000000000000..870dde0ba9b23 --- /dev/null +++ b/change/@fluentui-web-components-19128575-ce2e-40b1-8a3b-8334eb585f40.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "update clean file to .cjs and ensure rimraf is in dependency tree", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "none" +} diff --git a/packages/web-components/build/clean.js b/packages/web-components/build/clean.cjs similarity index 100% rename from packages/web-components/build/clean.js rename to packages/web-components/build/clean.cjs diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 3bed54f6654c0..074a49770078f 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -32,7 +32,7 @@ "scripts": { "tsc": "tsc", "api-extractor": "api-extractor", - "clean": "node ./build/clean.js dist", + "clean": "node ./build/clean.cjs dist", "doc": "api-extractor run --local", "doc:ci": "yarn doc", "build": "tsc -p ./tsconfig.json && rollup -c && yarn doc", @@ -84,6 +84,7 @@ "karma-webpack": "5.0.0", "mocha": "7.2.0", "@microsoft/api-extractor": "7.31.2", + "rimraf": "^3.0.2", "typescript": "4.7.4" }, "dependencies": { From 65d640f123534a75ce156bc672d5191c8873ca97 Mon Sep 17 00:00:00 2001 From: Martin Hochel Date: Wed, 18 Jan 2023 15:44:56 +0100 Subject: [PATCH 009/203] chore(web-components): resolve invalid webpack test regex on windows (#26402) --- ...eb-components-0b247950-52cb-4f3a-a1c3-9455ef090098.json | 7 +++++++ packages/web-components/.storybook/main.cjs | 2 +- .../web-components/.storybook/{manager.js => manager.mjs} | 0 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 change/@fluentui-web-components-0b247950-52cb-4f3a-a1c3-9455ef090098.json rename packages/web-components/.storybook/{manager.js => manager.mjs} (100%) diff --git a/change/@fluentui-web-components-0b247950-52cb-4f3a-a1c3-9455ef090098.json b/change/@fluentui-web-components-0b247950-52cb-4f3a-a1c3-9455ef090098.json new file mode 100644 index 0000000000000..58b7bdb89f803 --- /dev/null +++ b/change/@fluentui-web-components-0b247950-52cb-4f3a-a1c3-9455ef090098.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore(web-components): resolve invalid webpack test regex on windows", + "packageName": "@fluentui/web-components", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/packages/web-components/.storybook/main.cjs b/packages/web-components/.storybook/main.cjs index e42bb815bb8d9..681fab30011f0 100644 --- a/packages/web-components/.storybook/main.cjs +++ b/packages/web-components/.storybook/main.cjs @@ -42,7 +42,7 @@ module.exports = { // It also enables importing other packages without proper ESM extensions, but that should be avoided ! // @see https://webpack.js.org/configuration/module/#resolvefullyspecified { - test: /\.storybook\/.+\.m?js/, + test: /\.m?js/, resolve: { fullySpecified: false }, }, ); diff --git a/packages/web-components/.storybook/manager.js b/packages/web-components/.storybook/manager.mjs similarity index 100% rename from packages/web-components/.storybook/manager.js rename to packages/web-components/.storybook/manager.mjs From df7b75d1412cd84eb76381ec70c6ca05257d986f Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Wed, 18 Jan 2023 09:21:14 -0800 Subject: [PATCH 010/203] feat: add badge and counter badge as new components (#26357) * add badge as a new component * add counter badge as a new component * fix broken import and add export paths * use badge template for counter badge to render count * update badge svg styles and fix import syntax * fixup imports for stories * update partial with default styles * js extension missing from partial imports * update api report --- ...-25e8f64c-845e-401f-a7f8-c9472a5720df.json | 7 + packages/web-components/docs/api-report.md | 166 +++++++++ packages/web-components/package.json | 8 + .../src/badge/badge.definition.ts | 19 + .../web-components/src/badge/badge.options.ts | 82 +++++ .../web-components/src/badge/badge.stories.ts | 126 +++++++ .../web-components/src/badge/badge.styles.ts | 36 ++ .../src/badge/badge.template.ts | 18 + packages/web-components/src/badge/badge.ts | 58 ++++ packages/web-components/src/badge/define.ts | 4 + packages/web-components/src/badge/index.ts | 5 + .../counter-badge/counter-badge.definition.ts | 19 + .../counter-badge/counter-badge.options.ts | 78 +++++ .../counter-badge/counter-badge.stories.ts | 123 +++++++ .../src/counter-badge/counter-badge.styles.ts | 31 ++ .../counter-badge/counter-badge.template.ts | 16 + .../src/counter-badge/counter-badge.ts | 125 +++++++ .../src/counter-badge/define.ts | 4 + .../web-components/src/counter-badge/index.ts | 5 + packages/web-components/src/index.ts | 2 + packages/web-components/src/styles/index.ts | 1 + .../src/styles/partials/badge.partials.ts | 327 ++++++++++++++++++ .../src/styles/partials/index.ts | 1 + 23 files changed, 1261 insertions(+) create mode 100644 change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json create mode 100644 packages/web-components/src/badge/badge.definition.ts create mode 100644 packages/web-components/src/badge/badge.options.ts create mode 100644 packages/web-components/src/badge/badge.stories.ts create mode 100644 packages/web-components/src/badge/badge.styles.ts create mode 100644 packages/web-components/src/badge/badge.template.ts create mode 100644 packages/web-components/src/badge/badge.ts create mode 100644 packages/web-components/src/badge/define.ts create mode 100644 packages/web-components/src/badge/index.ts create mode 100644 packages/web-components/src/counter-badge/counter-badge.definition.ts create mode 100644 packages/web-components/src/counter-badge/counter-badge.options.ts create mode 100644 packages/web-components/src/counter-badge/counter-badge.stories.ts create mode 100644 packages/web-components/src/counter-badge/counter-badge.styles.ts create mode 100644 packages/web-components/src/counter-badge/counter-badge.template.ts create mode 100644 packages/web-components/src/counter-badge/counter-badge.ts create mode 100644 packages/web-components/src/counter-badge/define.ts create mode 100644 packages/web-components/src/counter-badge/index.ts create mode 100644 packages/web-components/src/styles/index.ts create mode 100644 packages/web-components/src/styles/partials/badge.partials.ts create mode 100644 packages/web-components/src/styles/partials/index.ts diff --git a/change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json b/change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json new file mode 100644 index 0000000000000..094c23a891496 --- /dev/null +++ b/change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "add badge and counter badge as new components", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/docs/api-report.md b/packages/web-components/docs/api-report.md index c027d600e8202..2796247c3e572 100644 --- a/packages/web-components/docs/api-report.md +++ b/packages/web-components/docs/api-report.md @@ -8,8 +8,174 @@ import { ElementStyles } from '@microsoft/fast-element'; import { ElementViewTemplate } from '@microsoft/fast-element'; import { FASTElement } from '@microsoft/fast-element'; import { FASTElementDefinition } from '@microsoft/fast-element'; +import { StartEnd } from '@microsoft/fast-foundation'; +import { StartEndOptions } from '@microsoft/fast-foundation'; +import { StaticallyComposableHTML } from '@microsoft/fast-foundation'; import { ValuesOf } from '@microsoft/fast-foundation'; +// Warning: (ae-internal-mixed-release-tag) Mixed release tags are not allowed for "Badge" because one of its declarations is marked as @internal +// +// @public +export class Badge extends FASTElement { + appearance: BadgeAppearance; + color: BadgeColor; + shape: BadgeShape; + size: BadgeSize; +} + +// @internal +export interface Badge extends StartEnd { +} + +// @public +export const BadgeAppearance: { + readonly filled: "filled"; + readonly ghost: "ghost"; + readonly outline: "outline"; + readonly tint: "tint"; +}; + +// @public +export type BadgeAppearance = ValuesOf; + +// @public +export const BadgeColor: { + readonly brand: "brand"; + readonly danger: "danger"; + readonly important: "important"; + readonly informative: "informative"; + readonly severe: "severe"; + readonly subtle: "subtle"; + readonly success: "success"; + readonly warning: "warning"; +}; + +// @public +export type BadgeColor = ValuesOf; + +// @public +export const BadgeDefinition: FASTElementDefinition; + +// Warning: (ae-internal-missing-underscore) The name "BadgeOptions" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal +export type BadgeOptions = StartEndOptions & { + defaultContent?: StaticallyComposableHTML; +}; + +// @public +export const BadgeShape: { + readonly circular: "circular"; + readonly rounded: "rounded"; + readonly square: "square"; +}; + +// @public +export type BadgeShape = ValuesOf; + +// @public +export const BadgeSize: { + readonly tiny: "tiny"; + readonly extraSmall: "extra-small"; + readonly small: "small"; + readonly medium: "medium"; + readonly large: "large"; + readonly extraLarge: "extra-large"; +}; + +// @public +export type BadgeSize = ValuesOf; + +// @public +export const BadgeStyles: ElementStyles; + +// @public (undocumented) +export const BadgeTemplate: ElementViewTemplate; + +// Warning: (ae-internal-mixed-release-tag) Mixed release tags are not allowed for "CounterBadge" because one of its declarations is marked as @internal +// +// @public +export class CounterBadge extends FASTElement { + appearance: CounterBadgeAppearance; + color: CounterBadgeColor; + count: number; + // (undocumented) + protected countChanged(): void; + dot: boolean; + overflowCount: number; + // (undocumented) + protected overflowCountChanged(): void; + // @internal + setCount(): string | void; + shape: CounterBadgeShape; + showZero: boolean; + size: CounterBadgeSize; +} + +// @internal +export interface CounterBadge extends StartEnd { +} + +// @public +export const CounterBadgeAppearance: { + readonly filled: "filled"; + readonly ghost: "ghost"; +}; + +// @public +export type CounterBadgeAppearance = ValuesOf; + +// @public +export const CounterBadgeColor: { + readonly brand: "brand"; + readonly danger: "danger"; + readonly important: "important"; + readonly informative: "informative"; + readonly severe: "severe"; + readonly subtle: "subtle"; + readonly success: "success"; + readonly warning: "warning"; +}; + +// @public +export type CounterBadgeColor = ValuesOf; + +// @public +export const CounterBadgeDefinition: FASTElementDefinition; + +// Warning: (ae-incompatible-release-tags) The symbol "CounterBadgeOptions" is marked as @public, but its signature references "BadgeOptions" which is marked as @internal +// +// @public +export type CounterBadgeOptions = BadgeOptions; + +// @public +export const CounterBadgeShape: { + readonly circular: "circular"; + readonly rounded: "rounded"; +}; + +// @public +export type CounterBadgeShape = ValuesOf; + +// @public +export const CounterBadgeSize: { + readonly tiny: "tiny"; + readonly extraSmall: "extra-small"; + readonly small: "small"; + readonly medium: "medium"; + readonly large: "large"; + readonly extraLarge: "extra-large"; +}; + +// @public +export type CounterBadgeSize = ValuesOf; + +// @public +export const CounterBadgeStyles: ElementStyles; + +// @public +export const CounterBadgeTemplate: ElementViewTemplate; + // @public class Text_2 extends FASTElement { align: TextAlign; diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 074a49770078f..67dfaf3eb1e3b 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -24,6 +24,14 @@ "types": "./dist/dts/index.d.ts", "default": "./dist/esm/index.js" }, + "./badge": { + "types": "./dist/esm/badge/define.d.ts", + "default": "./dist/esm/badge/define.js" + }, + "./counter-badge": { + "types": "./dist/esm/counter-badge/define.d.ts", + "default": "./dist/esm/counter-badge/define.js" + }, "./text": { "types": "./dist/esm/text/define.d.ts", "default": "./dist/esm/text/define.js" diff --git a/packages/web-components/src/badge/badge.definition.ts b/packages/web-components/src/badge/badge.definition.ts new file mode 100644 index 0000000000000..f15da6d05174f --- /dev/null +++ b/packages/web-components/src/badge/badge.definition.ts @@ -0,0 +1,19 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Badge } from './badge.js'; +import { styles } from './badge.styles.js'; +import { template } from './badge.template.js'; + +/** + * The Fluent Badge Element. Implements {@link @microsoft/fast-foundation#Badge }, + * {@link @microsoft/fast-foundation#badgeTemplate} + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = Badge.compose({ + name: `${FluentDesignSystem.prefix}-badge`, + template, + styles, +}); diff --git a/packages/web-components/src/badge/badge.options.ts b/packages/web-components/src/badge/badge.options.ts new file mode 100644 index 0000000000000..9fd2a6613ca89 --- /dev/null +++ b/packages/web-components/src/badge/badge.options.ts @@ -0,0 +1,82 @@ +import { StartEndOptions, StaticallyComposableHTML, ValuesOf } from '@microsoft/fast-foundation'; +import type { Badge } from './badge.js'; + +/** + * @internal - marking as internal update when Badge PR for start/end is in + */ +export type BadgeOptions = StartEndOptions & { + defaultContent?: StaticallyComposableHTML; +}; + +/** + * BadgeAppearance constants + * @public + */ +export const BadgeAppearance = { + filled: 'filled', + ghost: 'ghost', + outline: 'outline', + tint: 'tint', +} as const; + +/** + * A Badge can be filled, outline, ghost, inverted + * @public + */ +export type BadgeAppearance = ValuesOf; + +/** + * BadgeColor constants + * @public + */ +export const BadgeColor = { + brand: 'brand', + danger: 'danger', + important: 'important', + informative: 'informative', + severe: 'severe', + subtle: 'subtle', + success: 'success', + warning: 'warning', +} as const; + +/** + * A Badge can be one of preset colors + * @public + */ +export type BadgeColor = ValuesOf; + +/** + * A Badge can be square, circular or rounded. + * @public + */ +export const BadgeShape = { + circular: 'circular', + rounded: 'rounded', + square: 'square', +} as const; + +/** + * A Badge can be one of preset colors + * @public + */ +export type BadgeShape = ValuesOf; + +/** + * A Badge can be square, circular or rounded. + * @public + */ +export const BadgeSize = { + tiny: 'tiny', + extraSmall: 'extra-small', + small: 'small', + medium: 'medium', + large: 'large', + extraLarge: 'extra-large', +} as const; + +/** + * A Badge can be on of several preset sizes. + * @public + */ +export type BadgeSize = ValuesOf; diff --git a/packages/web-components/src/badge/badge.stories.ts b/packages/web-components/src/badge/badge.stories.ts new file mode 100644 index 0000000000000..f931eadf524be --- /dev/null +++ b/packages/web-components/src/badge/badge.stories.ts @@ -0,0 +1,126 @@ +import { html, when } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../__test__/helpers.js'; +import type { Badge as FluentBadge } from './badge.js'; +import { BadgeAppearance, BadgeColor, BadgeShape, BadgeSize } from './badge.options.js'; +import './define.js'; + +type BadgeStoryArgs = Args & FluentBadge; +type BadgeStoryMeta = Meta; + +const storyTemplate = html` + + ${when( + x => x.iconPosition === 'start', + html``, + )} + ${x => x.content} + ${when( + x => x.iconPosition === 'end', + html``, + )} + +`; + +export default { + title: 'Components/Badge/Badge', + args: { + content: null, + }, + argTypes: { + appearance: { + options: Object.values(BadgeAppearance), + control: { + type: 'select', + }, + }, + color: { + options: Object.values(BadgeColor), + control: { + type: 'select', + }, + }, + shape: { + options: Object.values(BadgeShape), + control: { + type: 'select', + }, + }, + size: { + options: Object.values(BadgeSize), + control: { + type: 'select', + }, + }, + iconPosition: { + options: ['none', 'start', 'end'], + control: { + type: 'select', + }, + }, + content: { + control: 'text', + }, + }, +} as BadgeStoryMeta; + +export const Badge = renderComponent(storyTemplate).bind({}); + +export const Appearance = renderComponent(html` + filled + ghost + outline + tint +`); + +export const Color = renderComponent(html` + brand + danger + important + informative + severe + subtle + success + warning +`); + +export const Shape = renderComponent(html` + + + +`); + +export const Size = renderComponent(html` + + + + + + +`) as BadgeStoryMeta; diff --git a/packages/web-components/src/badge/badge.styles.ts b/packages/web-components/src/badge/badge.styles.ts new file mode 100644 index 0000000000000..64da6c5d16470 --- /dev/null +++ b/packages/web-components/src/badge/badge.styles.ts @@ -0,0 +1,36 @@ +import { css } from '@microsoft/fast-element'; +import { + badgeBaseStyles, + badgeFilledStyles, + badgeGhostStyles, + badgeOutlineStyles, + badgeSizeStyles, + badgeTintStyles, +} from '../styles/index.js'; +import { borderRadiusMedium, borderRadiusNone, borderRadiusSmall } from '../theme/design-tokens.js'; +// why is the border not showing up? +/** Badge styles + * @public + */ +export const styles = css` + :host([shape='square']) { + border-radius: ${borderRadiusNone}; + } + + :host([shape='rounded']) { + border-radius: ${borderRadiusMedium}; + } + + :host([shape='rounded'][size='tiny']), + :host([shape='rounded'][size='extra-small']), + :host([shape='rounded'][size='small']) { + border-radius: ${borderRadiusSmall}; + } + + ${badgeSizeStyles} + ${badgeFilledStyles} + ${badgeGhostStyles} + ${badgeOutlineStyles} + ${badgeTintStyles} + ${badgeBaseStyles} +`; diff --git a/packages/web-components/src/badge/badge.template.ts b/packages/web-components/src/badge/badge.template.ts new file mode 100644 index 0000000000000..1b4fab522ff87 --- /dev/null +++ b/packages/web-components/src/badge/badge.template.ts @@ -0,0 +1,18 @@ +import { ElementViewTemplate, html } from '@microsoft/fast-element'; +import { endSlotTemplate, startSlotTemplate, staticallyCompose } from '@microsoft/fast-foundation'; +import type { Badge } from './badge.js'; +import type { BadgeOptions } from './badge.options.js'; + +/** + * The template for the Badge component. + * @public + */ +export function badgeTemplate(options: BadgeOptions = {}): ElementViewTemplate { + return html` + ${startSlotTemplate(options)} + ${staticallyCompose(options.defaultContent)} + ${endSlotTemplate(options)} + `; +} + +export const template: ElementViewTemplate = badgeTemplate(); diff --git a/packages/web-components/src/badge/badge.ts b/packages/web-components/src/badge/badge.ts new file mode 100644 index 0000000000000..25481e08d57a5 --- /dev/null +++ b/packages/web-components/src/badge/badge.ts @@ -0,0 +1,58 @@ +import { attr, FASTElement } from '@microsoft/fast-element'; +import { applyMixins, StartEnd } from '@microsoft/fast-foundation'; +import { BadgeAppearance, BadgeColor, BadgeShape, BadgeSize } from './badge.options.js'; + +/** + * The base class used for constructing a fluent-badge custom element + * @public + */ +export class Badge extends FASTElement { + /** + * The appearance the badge should have. + * + * @public + * @remarks + * HTML Attribute: appearance + */ + @attr + public appearance: BadgeAppearance = BadgeAppearance.filled; + + /** + * The color the badge should have. + * + * @public + * @remarks + * HTML Attribute: color + */ + @attr + public color: BadgeColor = BadgeColor.brand; + /** + * The shape the badge should have. + * + * @public + * @remarks + * HTML Attribute: shape + */ + @attr + public shape: BadgeShape; + + /** + * The size the badge should have. + * + * @public + * @remarks + * HTML Attribute: size + */ + @attr + public size: BadgeSize; +} + +/** + * Mark internal because exporting class and interface of the same name + * confuses API extractor. + * TODO: Below will be unnecessary when Badge class gets updated + * @internal + */ +/* eslint-disable-next-line */ +export interface Badge extends StartEnd {} +applyMixins(Badge, StartEnd); diff --git a/packages/web-components/src/badge/define.ts b/packages/web-components/src/badge/define.ts new file mode 100644 index 0000000000000..d0e348b49c9c9 --- /dev/null +++ b/packages/web-components/src/badge/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './badge.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/badge/index.ts b/packages/web-components/src/badge/index.ts new file mode 100644 index 0000000000000..92e3fdcd87214 --- /dev/null +++ b/packages/web-components/src/badge/index.ts @@ -0,0 +1,5 @@ +export * from './badge.js'; +export * from './badge.options.js'; +export { template as BadgeTemplate } from './badge.template.js'; +export { styles as BadgeStyles } from './badge.styles.js'; +export { definition as BadgeDefinition } from './badge.definition.js'; diff --git a/packages/web-components/src/counter-badge/counter-badge.definition.ts b/packages/web-components/src/counter-badge/counter-badge.definition.ts new file mode 100644 index 0000000000000..2520d85972b6d --- /dev/null +++ b/packages/web-components/src/counter-badge/counter-badge.definition.ts @@ -0,0 +1,19 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { CounterBadge } from './counter-badge.js'; +import { styles } from './counter-badge.styles.js'; +import { template } from './counter-badge.template.js'; + +/** + * The Fluent CounterBadge Element. Implements {@link @microsoft/fast-foundation#Badge }, + * {@link @microsoft/fast-foundation#badgeTemplate} + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = CounterBadge.compose({ + name: `${FluentDesignSystem.prefix}-counter-badge`, + template, + styles, +}); diff --git a/packages/web-components/src/counter-badge/counter-badge.options.ts b/packages/web-components/src/counter-badge/counter-badge.options.ts new file mode 100644 index 0000000000000..02db6af0a483e --- /dev/null +++ b/packages/web-components/src/counter-badge/counter-badge.options.ts @@ -0,0 +1,78 @@ +import { ValuesOf } from '@microsoft/fast-foundation'; +import { BadgeOptions } from '../badge/badge.options.js'; + +/** + * CounterBadge options + * @public + */ +export type CounterBadgeOptions = BadgeOptions; + +/** + * CounterBadgeAppearance constants + * @public + */ +export const CounterBadgeAppearance = { + filled: 'filled', + ghost: 'ghost', +} as const; + +/** + * A CounterBadge can have an appearance of filled or ghost + * @public + */ +export type CounterBadgeAppearance = ValuesOf; + +/** + * CounterBadgeColor constants + * @public + */ +export const CounterBadgeColor = { + brand: 'brand', + danger: 'danger', + important: 'important', + informative: 'informative', + severe: 'severe', + subtle: 'subtle', + success: 'success', + warning: 'warning', +} as const; + +/** + * A CounterBadge can be one of preset colors + * @public + */ +export type CounterBadgeColor = ValuesOf; + +/** + * A CounterBadge shape can be circular or rounded. + * @public + */ +export const CounterBadgeShape = { + circular: 'circular', + rounded: 'rounded', +} as const; + +/** + * A CounterBadge can be one of preset colors + * @public + */ +export type CounterBadgeShape = ValuesOf; + +/** + * A CounterBadge can be square, circular or rounded. + * @public + */ +export const CounterBadgeSize = { + tiny: 'tiny', + extraSmall: 'extra-small', + small: 'small', + medium: 'medium', + large: 'large', + extraLarge: 'extra-large', +} as const; + +/** + * A CounterBadge can be on of several preset sizes. + * @public + */ +export type CounterBadgeSize = ValuesOf; diff --git a/packages/web-components/src/counter-badge/counter-badge.stories.ts b/packages/web-components/src/counter-badge/counter-badge.stories.ts new file mode 100644 index 0000000000000..aa3011ade4622 --- /dev/null +++ b/packages/web-components/src/counter-badge/counter-badge.stories.ts @@ -0,0 +1,123 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../__test__/helpers.js'; +import type { CounterBadge as FluentCounterBadge } from './counter-badge.js'; +import { + CounterBadgeAppearance, + CounterBadgeColor, + CounterBadgeShape, + CounterBadgeSize, +} from './counter-badge.options.js'; +import './define.js'; + +type CounterBadgeStoryArgs = Args & FluentCounterBadge; +type CounterBadgeStoryMeta = Meta; + +// TODO: Currently cannot show icon or content +// in the counter badge stories because it projects as slotted content +const storyTemplate = html` + +`; + +export default { + title: 'Components/Badge/Counter Badge', + args: { + dot: false, + showZero: false, + appearance: CounterBadgeAppearance.filled, + color: CounterBadgeColor.brand, + shape: CounterBadgeShape.circular, + count: 5, + }, + argTypes: { + appearance: { + options: Object.values(CounterBadgeAppearance), + control: { + type: 'select', + }, + }, + color: { + options: Object.values(CounterBadgeColor), + control: { + type: 'select', + }, + }, + shape: { + options: Object.values(CounterBadgeShape), + control: { + type: 'select', + }, + }, + size: { + options: Object.values(CounterBadgeSize), + control: { + type: 'select', + }, + }, + iconPosition: { + options: ['none', 'start', 'end'], + control: { + type: 'select', + }, + }, + dot: { + control: 'boolean', + }, + showZero: { + control: 'boolean', + }, + count: { + control: 'number', + }, + overflowCount: { + control: 'text', + }, + }, +} as CounterBadgeStoryMeta; + +export const CounterBadge = renderComponent(storyTemplate).bind({}); + +export const Appearance = renderComponent(html` + + +`); + +export const Color = renderComponent(html` + + + + + + + + +`); + +export const Shape = renderComponent(html` + + +`); + +export const Size = renderComponent(html` + + + + + + +`) as CounterBadgeStoryMeta; + +export const Dot = renderComponent(html``); + +export const ShowZero = renderComponent( + html``, +); diff --git a/packages/web-components/src/counter-badge/counter-badge.styles.ts b/packages/web-components/src/counter-badge/counter-badge.styles.ts new file mode 100644 index 0000000000000..7db498fccc673 --- /dev/null +++ b/packages/web-components/src/counter-badge/counter-badge.styles.ts @@ -0,0 +1,31 @@ +import { css } from '@microsoft/fast-element'; +import { badgeBaseStyles, badgeFilledStyles, badgeGhostStyles, badgeSizeStyles } from '../styles/index.js'; +import { borderRadiusMedium, borderRadiusSmall } from '../theme/design-tokens.js'; + +/** Badge styles + * @public + */ +export const styles = css` + :host([shape='rounded']) { + border-radius: ${borderRadiusMedium}; + } + + :host([shape='rounded'][size='tiny']), + :host([shape='rounded'][size='extra-small']), + :host([shape='rounded'][size='small']) { + border-radius: ${borderRadiusSmall}; + } + + ${badgeSizeStyles} + ${badgeFilledStyles} + ${badgeGhostStyles} + ${badgeBaseStyles} + + :host([dot]), + :host([dot][appearance][size]) { + min-width: auto; + width: 6px; + height: 6px; + padding: 0; + } +`; diff --git a/packages/web-components/src/counter-badge/counter-badge.template.ts b/packages/web-components/src/counter-badge/counter-badge.template.ts new file mode 100644 index 0000000000000..f0049a3abc528 --- /dev/null +++ b/packages/web-components/src/counter-badge/counter-badge.template.ts @@ -0,0 +1,16 @@ +import { ElementViewTemplate, html } from '@microsoft/fast-element'; +import { badgeTemplate } from '../badge/badge.template.js'; +import { CounterBadge } from './counter-badge.js'; +import { CounterBadgeOptions } from './counter-badge.options.js'; + +function composeTemplate(options: CounterBadgeOptions = {}): ElementViewTemplate { + return badgeTemplate({ + defaultContent: html`${x => x.setCount()}`, + }); +} + +/** + * The template for the Counter Badge component. + * @public + */ +export const template: ElementViewTemplate = composeTemplate(); diff --git a/packages/web-components/src/counter-badge/counter-badge.ts b/packages/web-components/src/counter-badge/counter-badge.ts new file mode 100644 index 0000000000000..38ca98713df4b --- /dev/null +++ b/packages/web-components/src/counter-badge/counter-badge.ts @@ -0,0 +1,125 @@ +import { attr, FASTElement, nullableNumberConverter } from '@microsoft/fast-element'; +import { applyMixins, StartEnd } from '@microsoft/fast-foundation'; +import { + CounterBadgeAppearance, + CounterBadgeColor, + CounterBadgeShape, + CounterBadgeSize, +} from './counter-badge.options.js'; + +/** + * The base class used for constructing a fluent-badge custom element + * @public + */ +export class CounterBadge extends FASTElement { + /** + * The appearance the badge should have. + * + * @public + * @remarks + * HTML Attribute: appearance + */ + @attr + public appearance: CounterBadgeAppearance; + + /** + * The color the badge should have. + * + * @public + * @remarks + * HTML Attribute: color + */ + @attr + public color: CounterBadgeColor; + /** + * The shape the badge should have. + * + * @public + * @remarks + * HTML Attribute: shape + */ + @attr + public shape: CounterBadgeShape; + + /** + * The size the badge should have. + * + * @public + * @remarks + * HTML Attribute: size + */ + @attr + public size: CounterBadgeSize; + + /** + * The count the badge should have. + * + * @public + * @remarks + * HTML Attribute: count + */ + @attr({ converter: nullableNumberConverter }) + public count: number = 0; + protected countChanged() { + this.setCount(); + } + + /** + * Max number to be displayed + * + * @public + * @remarks + * HTML Attribute: overflow-count + */ + @attr({ attribute: 'overflow-count', converter: nullableNumberConverter }) + public overflowCount: number = 99; + protected overflowCountChanged() { + this.setCount(); + } + + /** + * If the badge should be shown when count is 0 + * + * @public + * @remarks + * HTML Attribute: show-zero + */ + @attr({ attribute: 'show-zero', mode: 'boolean' }) + public showZero: boolean = false; + + /** + * If a dot should be displayed without the count + * + * @public + * @remarks + * HTML Attribute: dot + */ + @attr({ mode: 'boolean' }) + public dot: boolean = false; + + /** + * @internal + * Function to set the count + * This is the default slotted content for the counter badge + * If children are slotted, that will override the value returned + */ + public setCount(): string | void { + const count: number | null = this.count ?? 0; + + if ((count !== 0 || this.showZero) && !this.dot) { + return count > this.overflowCount ? `${this.overflowCount}+` : `${count}`; + } + + return; + } +} + +/** + * Mark internal because exporting class and interface of the same name + * confuses API extractor. + * TODO: Below will be unnecessary when Badge class gets updated + * @internal + */ +/* eslint-disable-next-line */ +export interface CounterBadge extends StartEnd {} +applyMixins(CounterBadge, StartEnd); diff --git a/packages/web-components/src/counter-badge/define.ts b/packages/web-components/src/counter-badge/define.ts new file mode 100644 index 0000000000000..e08fef18aeccb --- /dev/null +++ b/packages/web-components/src/counter-badge/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './counter-badge.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/counter-badge/index.ts b/packages/web-components/src/counter-badge/index.ts new file mode 100644 index 0000000000000..159c31d2e2f94 --- /dev/null +++ b/packages/web-components/src/counter-badge/index.ts @@ -0,0 +1,5 @@ +export * from './counter-badge.js'; +export * from './counter-badge.options.js'; +export { template as CounterBadgeTemplate } from './counter-badge.template.js'; +export { styles as CounterBadgeStyles } from './counter-badge.styles.js'; +export { definition as CounterBadgeDefinition } from './counter-badge.definition.js'; diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index dd622fd56e566..bd9a8b7c5b0b6 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -1 +1,3 @@ +export * from './badge/index.js'; +export * from './counter-badge/index.js'; export * from './text/index.js'; diff --git a/packages/web-components/src/styles/index.ts b/packages/web-components/src/styles/index.ts new file mode 100644 index 0000000000000..8613859ad3e89 --- /dev/null +++ b/packages/web-components/src/styles/index.ts @@ -0,0 +1 @@ +export * from './partials/index.js'; diff --git a/packages/web-components/src/styles/partials/badge.partials.ts b/packages/web-components/src/styles/partials/badge.partials.ts new file mode 100644 index 0000000000000..cb1263e59d458 --- /dev/null +++ b/packages/web-components/src/styles/partials/badge.partials.ts @@ -0,0 +1,327 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + borderRadiusCircular, + colorBrandBackground, + colorBrandBackground2, + colorBrandForeground1, + colorBrandForeground2, + colorBrandStroke2, + colorNeutralBackground1, + colorNeutralBackground4, + colorNeutralBackground5, + colorNeutralForeground1, + colorNeutralForeground3, + colorNeutralForegroundInverted, + colorNeutralForegroundOnBrand, + colorNeutralForegroundStaticInverted, + colorNeutralStroke2, + colorNeutralStrokeAccessible, + colorPaletteDarkOrangeBackground1, + colorPaletteDarkOrangeBackground3, + colorPaletteDarkOrangeBorder1, + colorPaletteDarkOrangeForeground1, + colorPaletteDarkOrangeForeground3, + colorPaletteGreenBackground1, + colorPaletteGreenBackground3, + colorPaletteGreenBorder2, + colorPaletteGreenForeground1, + colorPaletteGreenForeground2, + colorPaletteGreenForeground3, + colorPaletteRedBackground1, + colorPaletteRedBackground3, + colorPaletteRedBorder1, + colorPaletteRedForeground1, + colorPaletteRedForeground3, + colorPaletteYellowBackground1, + colorPaletteYellowBackground3, + colorPaletteYellowBorder1, + colorPaletteYellowForeground2, + colorTransparentStroke, + fontFamilyBase, + fontSizeBase100, + fontSizeBase200, + fontWeightSemibold, + lineHeightBase100, + lineHeightBase200, + spacingHorizontalSNudge, + spacingHorizontalXS, + spacingHorizontalXXS, + strokeWidthThin, +} from '../../theme/design-tokens.js'; + +const textPadding = spacingHorizontalXXS; + +export const badgeBaseStyles = css.partial` + ${display('inline-flex')} :host { + position: relative; + box-sizing: border-box; + align-items: center; + justify-content: center; + font-family: ${fontFamilyBase}; + font-weight: ${fontWeightSemibold}; + font-size: ${fontSizeBase200}; + line-height: ${lineHeightBase200}; + min-width: 20px; + height: 20px; + padding-inline: calc(${spacingHorizontalXS} + ${textPadding}); + border-radius: ${borderRadiusCircular}; + border-color: ${colorTransparentStroke}; + background-color: ${colorBrandBackground}; + color: ${colorNeutralForegroundOnBrand}; + } + + ::slotted(svg) { + font-size: 12px; + } + + :host(:not([appearance='ghost']))::after { + position: absolute; + content: ''; + top: 0; + left: 0; + bottom: 0; + right: 0; + border-style: solid; + border-width: ${strokeWidthThin}; + border-color: inherit; + border-radius: inherit; + } +`; + +/** + * @public + * The badge's size styles + */ +export const badgeSizeStyles = css.partial` + :host([size='tiny']) { + width: 6px; + height: 6px; + font-size: 4px; + line-height: 4px; + padding-inline: 0; + min-width: unset; + } + :host([size='tiny']) ::slotted(svg) { + font-size: 6px; + } + :host([size='extra-small']) { + width: 10px; + height: 10px; + font-size: 6px; + line-height: 6px; + padding-inline: 0; + min-width: unset; + } + :host([size='extra-small']) ::slotted(svg) { + font-size: 10px; + } + :host([size='small']) { + min-width: 16px; + height: 16px; + font-size: ${fontSizeBase100}; + line-height: ${lineHeightBase100}; + padding-inline: calc(${spacingHorizontalXXS} + ${textPadding}); + } + :host([size='small']) ::slotted(svg) { + font-size: 12px; + } + :host([size='large']) { + min-width: 24px; + height: 24px; + font-size: ${fontSizeBase200}; + line-height: ${lineHeightBase200}; + padding-inline: calc(${spacingHorizontalXS} + ${textPadding}); + } + :host([size='large']) ::slotted(svg) { + font-size: 16px; + } + :host([size='extra-large']) { + min-width: 32px; + height: 32px; + font-size: ${fontSizeBase200}; + line-height: ${lineHeightBase200}; + padding-inline: calc(${spacingHorizontalSNudge} + ${textPadding}); + } + :host([size='extra-large']) ::slotted(svg) { + font-size: 20px; + } +`; + +/** + * The badge's `filled` appearance styles + * Filled appearance is default so do not + * Include that attribute as it's not present by default + * @public + */ +export const badgeFilledStyles = css.partial` + :host([color='danger']) { + background-color: ${colorPaletteRedBackground3}; + color: ${colorNeutralForegroundOnBrand}; + } + + :host([color='important']) { + background-color: ${colorNeutralForeground1}; + color: ${colorNeutralBackground1}; + } + + :host([color='informative']) { + background-color: ${colorNeutralBackground5}; + color: ${colorNeutralForeground3}; + } + + :host([color='severe']) { + background-color: ${colorPaletteDarkOrangeBackground3}; + color: ${colorNeutralForegroundOnBrand}; + } + + :host([color='subtle']) { + background-color: ${colorNeutralBackground1}; + color: ${colorNeutralForeground1}; + } + + :host([color='success']) { + background-color: ${colorPaletteGreenBackground3}; + color: ${colorNeutralForegroundOnBrand}; + } + + :host([color='warning']) { + background-color: ${colorPaletteYellowBackground3}; + color: ${colorNeutralForeground1}; + } +`; + +/** + * The badge's `ghost` appearance styles + * @public + */ +export const badgeGhostStyles = css.partial` + :host([appearance='ghost']) { + color: ${colorBrandBackground}; + background-color: initial; + } + + :host([appearance='ghost'][color='danger']) { + color: ${colorPaletteRedForeground3}; + } + + :host([appearance='ghost'][color='important']) { + color: ${colorNeutralForeground1}; + } + + :host([appearance='ghost'][color='informative']) { + color: ${colorNeutralForeground3}; + } + + :host([appearance='ghost'][color='severe']) { + color: ${colorPaletteDarkOrangeForeground3}; + } + + :host([appearance='ghost'][color='subtle']) { + color: ${colorNeutralForegroundInverted}; + } + + :host([appearance='ghost'][color='success']) { + color: ${colorPaletteGreenForeground3}; + } + + :host([appearance='ghost'][color='warning']) { + color: ${colorPaletteYellowForeground2}; + } +`; + +/** + * The badge's `outline` appearance styles + * @public + */ +export const badgeOutlineStyles = css.partial` + :host([appearance='outline']) { + border-color: currentColor; + color: ${colorBrandForeground1}; + background-color: initial; + } + + :host([appearance='outline'][color='danger']) { + color: ${colorPaletteRedForeground3}; + } + + :host([appearance='outline'][color='important']) { + color: ${colorNeutralForeground3}; + border-color: ${colorNeutralStrokeAccessible}; + } + + :host([appearance='outline'][color='informative']) { + color: ${colorNeutralForeground3}; + border-color: ${colorNeutralStroke2}; + } + + :host([appearance='outline'][color='severe']) { + color: ${colorPaletteDarkOrangeForeground3}; + } + + :host([appearance='outline'][color='subtle']) { + color: ${colorNeutralForegroundStaticInverted}; + } + + :host([appearance='outline'][color='success']) { + color: ${colorPaletteGreenForeground2}; + } + + :host([appearance='outline'][color='warning']) { + color: ${colorPaletteYellowForeground2}; + } +`; + +/** + * The badge's `tint` appearance styles + * @public + */ +export const badgeTintStyles = css.partial` + :host([appearance='tint']) { + background-color: ${colorBrandBackground2}; + color: ${colorBrandForeground2}; + border-color: ${colorBrandStroke2}; + } + + :host([appearance='tint'][color='danger']) { + background-color: ${colorPaletteRedBackground1}; + color: ${colorPaletteRedForeground1}; + border-color: ${colorPaletteRedBorder1}; + } + + :host([appearance='tint'][color='important']) { + background-color: ${colorNeutralForeground3}; + color: ${colorNeutralBackground1}; + border-color: ${colorTransparentStroke}; + } + + :host([appearance='tint'][color='informative']) { + background-color: ${colorNeutralBackground4}; + color: ${colorNeutralForeground3}; + border-color: ${colorNeutralStroke2}; + } + + :host([appearance='tint'][color='severe']) { + background-color: ${colorPaletteDarkOrangeBackground1}; + color: ${colorPaletteDarkOrangeForeground1}; + border-color: ${colorPaletteDarkOrangeBorder1}; + } + + :host([appearance='tint'][color='subtle']) { + background-color: ${colorNeutralBackground1}; + color: ${colorNeutralForeground3}; + border-color: ${colorNeutralStroke2}; + } + + :host([appearance='tint'][color='success']) { + background-color: ${colorPaletteGreenBackground1}; + color: ${colorPaletteGreenForeground1}; + border-color: ${colorPaletteGreenBorder2}; + } + + :host([appearance='tint'][color='warning']) { + background-color: ${colorPaletteYellowBackground1}; + color: ${colorPaletteYellowForeground2}; + border-color: ${colorPaletteYellowBorder1}; + } +`; diff --git a/packages/web-components/src/styles/partials/index.ts b/packages/web-components/src/styles/partials/index.ts new file mode 100644 index 0000000000000..c7515fc1e06b2 --- /dev/null +++ b/packages/web-components/src/styles/partials/index.ts @@ -0,0 +1 @@ +export * from './badge.partials.js'; From 831af4d623da7c4fb25a7c37f8dea8f3f4052bc4 Mon Sep 17 00:00:00 2001 From: Ryan Merrill Date: Wed, 18 Jan 2023 12:54:58 -0800 Subject: [PATCH 011/203] Users/procload/add progressbar as new component (#26329) * Adds web component version of ProgressBar * Generates change * Renames progressbar to progress-bar * Changes alphabetical ordering of imports * Enumerates null value; Adds ? to boolean in Story * Adds typedocs to progress-bar class * Fixes class to attribute typo in CSS * Removes duped CSS * Adds export of progress-bar to package.json * Removes null in validation state object * Removes local CSS variables; Removes defaults on thickness and rounded corners * Removes unused CSS * Removes unused options, pause and min, that don't exist in Fluent * Addresses remaining feedback on PR: Renames rect to square; Cleans up Storybook --- ...-d423d05a-1b1e-422f-ab9a-afc288197681.json | 7 + packages/web-components/docs/api-report.md | 45 +++++ packages/web-components/package.json | 4 + packages/web-components/src/index.ts | 1 + .../web-components/src/progress-bar/define.ts | 4 + .../web-components/src/progress-bar/index.ts | 5 + .../progress-bar/progress-bar.definition.ts | 18 ++ .../src/progress-bar/progress-bar.options.ts | 47 +++++ .../src/progress-bar/progress-bar.stories.ts | 69 ++++++++ .../src/progress-bar/progress-bar.styles.ts | 167 ++++++++++++++++++ .../src/progress-bar/progress-bar.template.ts | 8 + .../src/progress-bar/progress-bar.ts | 37 ++++ 12 files changed, 412 insertions(+) create mode 100644 change/@fluentui-web-components-d423d05a-1b1e-422f-ab9a-afc288197681.json create mode 100644 packages/web-components/src/progress-bar/define.ts create mode 100644 packages/web-components/src/progress-bar/index.ts create mode 100644 packages/web-components/src/progress-bar/progress-bar.definition.ts create mode 100644 packages/web-components/src/progress-bar/progress-bar.options.ts create mode 100644 packages/web-components/src/progress-bar/progress-bar.stories.ts create mode 100644 packages/web-components/src/progress-bar/progress-bar.styles.ts create mode 100644 packages/web-components/src/progress-bar/progress-bar.template.ts create mode 100644 packages/web-components/src/progress-bar/progress-bar.ts diff --git a/change/@fluentui-web-components-d423d05a-1b1e-422f-ab9a-afc288197681.json b/change/@fluentui-web-components-d423d05a-1b1e-422f-ab9a-afc288197681.json new file mode 100644 index 0000000000000..cd6c5c717b627 --- /dev/null +++ b/change/@fluentui-web-components-d423d05a-1b1e-422f-ab9a-afc288197681.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "add progressbar as new component", + "packageName": "@fluentui/web-components", + "email": "ryan@ryanmerrill.net", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/docs/api-report.md b/packages/web-components/docs/api-report.md index 2796247c3e572..42d325f15e064 100644 --- a/packages/web-components/docs/api-report.md +++ b/packages/web-components/docs/api-report.md @@ -8,6 +8,7 @@ import { ElementStyles } from '@microsoft/fast-element'; import { ElementViewTemplate } from '@microsoft/fast-element'; import { FASTElement } from '@microsoft/fast-element'; import { FASTElementDefinition } from '@microsoft/fast-element'; +import { FASTProgress } from '@microsoft/fast-foundation'; import { StartEnd } from '@microsoft/fast-foundation'; import { StartEndOptions } from '@microsoft/fast-foundation'; import { StaticallyComposableHTML } from '@microsoft/fast-foundation'; @@ -176,6 +177,50 @@ export const CounterBadgeStyles: ElementStyles; // @public export const CounterBadgeTemplate: ElementViewTemplate; +// @public +export class ProgressBar extends FASTProgress { + shape: ProgressBarShape; + thickness: ProgressBarThickness; + validationState: ProgressBarValidationState | null; +} + +// @public +export const ProgressBarDefinition: FASTElementDefinition; + +// @public +export const ProgressBarShape: { + readonly rounded: "rounded"; + readonly square: "square"; +}; + +// @public +export type ProgressBarShape = ValuesOf; + +// @public +export const ProgressBarStyles: ElementStyles; + +// @public (undocumented) +export const ProgressBarTemplate: ElementViewTemplate; + +// @public +export const ProgressBarThickness: { + readonly medium: "medium"; + readonly large: "large"; +}; + +// @public +export type ProgressBarThickness = ValuesOf; + +// @public +export const ProgressBarValidationState: { + readonly success: "success"; + readonly warning: "warning"; + readonly error: "error"; +}; + +// @public +export type ProgressBarValidationState = ValuesOf; + // @public class Text_2 extends FASTElement { align: TextAlign; diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 67dfaf3eb1e3b..ce1b78ab89936 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -35,6 +35,10 @@ "./text": { "types": "./dist/esm/text/define.d.ts", "default": "./dist/esm/text/define.js" + }, + "./progress-bar": { + "types": "./dist/esm/progress-bar/define.d.ts", + "default": "./dist/esm/progress-bar/define.js" } }, "scripts": { diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index bd9a8b7c5b0b6..0feb1f29f22f0 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -1,3 +1,4 @@ export * from './badge/index.js'; export * from './counter-badge/index.js'; +export * from './progress-bar/index.js'; export * from './text/index.js'; diff --git a/packages/web-components/src/progress-bar/define.ts b/packages/web-components/src/progress-bar/define.ts new file mode 100644 index 0000000000000..a0bf72c3f6d6a --- /dev/null +++ b/packages/web-components/src/progress-bar/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './progress-bar.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/progress-bar/index.ts b/packages/web-components/src/progress-bar/index.ts new file mode 100644 index 0000000000000..8689e08b832e3 --- /dev/null +++ b/packages/web-components/src/progress-bar/index.ts @@ -0,0 +1,5 @@ +export * from './progress-bar.js'; +export * from './progress-bar.options.js'; +export { definition as ProgressBarDefinition } from './progress-bar.definition.js'; +export { styles as ProgressBarStyles } from './progress-bar.styles.js'; +export { template as ProgressBarTemplate } from './progress-bar.template.js'; diff --git a/packages/web-components/src/progress-bar/progress-bar.definition.ts b/packages/web-components/src/progress-bar/progress-bar.definition.ts new file mode 100644 index 0000000000000..0e0afa49b1aa5 --- /dev/null +++ b/packages/web-components/src/progress-bar/progress-bar.definition.ts @@ -0,0 +1,18 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { ProgressBar } from './progress-bar.js'; +import { styles } from './progress-bar.styles.js'; +import { template } from './progress-bar.template.js'; + +/** + * The Fluent ProgressBar Element. + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = ProgressBar.compose({ + name: `${FluentDesignSystem.prefix}-progress-bar`, + template, + styles, +}); diff --git a/packages/web-components/src/progress-bar/progress-bar.options.ts b/packages/web-components/src/progress-bar/progress-bar.options.ts new file mode 100644 index 0000000000000..21e5947c60952 --- /dev/null +++ b/packages/web-components/src/progress-bar/progress-bar.options.ts @@ -0,0 +1,47 @@ +import { ValuesOf } from '@microsoft/fast-foundation'; + +/** + * ProgressBarThickness Constants + * @public + */ +export const ProgressBarThickness = { + medium: 'medium', + large: 'large', +} as const; + +/** + * Applies bar thickness to the content + * @public + */ +export type ProgressBarThickness = ValuesOf; + +/** + * ProgressBarShape Constants + * @public + */ +export const ProgressBarShape = { + rounded: 'rounded', + square: 'square', +} as const; + +/** + * Applies bar shape to the content + * @public + */ +export type ProgressBarShape = ValuesOf; + +/** + * ProgressBarValidationState Constants + * @public + */ +export const ProgressBarValidationState = { + success: 'success', + warning: 'warning', + error: 'error', +} as const; + +/** + * Applies validation state to the content + * @public + */ +export type ProgressBarValidationState = ValuesOf; diff --git a/packages/web-components/src/progress-bar/progress-bar.stories.ts b/packages/web-components/src/progress-bar/progress-bar.stories.ts new file mode 100644 index 0000000000000..bd9203fff8c26 --- /dev/null +++ b/packages/web-components/src/progress-bar/progress-bar.stories.ts @@ -0,0 +1,69 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../__test__/helpers.js'; +import type { ProgressBar as FluentProgressBar } from './progress-bar.js'; +import { ProgressBarShape, ProgressBarThickness, ProgressBarValidationState } from './progress-bar.options.js'; +import './define.js'; + +type ProgressStoryArgs = Args & FluentProgressBar; +type ProgressStoryMeta = Meta; + +const storyTemplate = html` + x.thickness} + shape=${x => x.shape} + max=${x => x.max} + aria-valuemax=${x => x.max} + aria-valuenow=${x => x.value} + value=${x => x.value} + validation-state=${x => x.validationState} + > +`; + +export default { + title: 'Components/ProgressBar', + args: { + max: 100, + value: 15, + thickness: 'medium', + shape: 'rounded', + validationState: null, + }, + argTypes: { + max: { + control: 'number', + defaultValue: 100, + }, + value: { + control: 'number', + defaultValue: 15, + }, + thickness: { + control: { + type: 'select', + }, + options: Object.values(ProgressBarThickness), + defaultValue: 'medium', + }, + shape: { + options: Object.values(ProgressBarShape), + control: { + type: 'select', + }, + defaultValue: 'rounded', + }, + validationState: { + options: Object.values(ProgressBarValidationState), + control: { + type: 'select', + }, + defaultValue: null, + }, + }, +} as ProgressStoryMeta; + +export const Progress = renderComponent(storyTemplate).bind({}); + +export const ProgressIndeterminate = renderComponent(html` + +`); diff --git a/packages/web-components/src/progress-bar/progress-bar.styles.ts b/packages/web-components/src/progress-bar/progress-bar.styles.ts new file mode 100644 index 0000000000000..281d19ffb5545 --- /dev/null +++ b/packages/web-components/src/progress-bar/progress-bar.styles.ts @@ -0,0 +1,167 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + borderRadiusMedium, + colorBrandBackground2, + colorCompoundBrandBackground, + colorNeutralBackground6, + colorPaletteDarkOrangeBackground2, + colorPaletteDarkOrangeBackground3, + colorPaletteGreenBackground2, + colorPaletteGreenBackground3, + colorPaletteRedBackground2, + colorPaletteRedBackground3, +} from '../theme/design-tokens.js'; + +/** Text styles + * @public + */ +export const styles = css` + ${display('flex')} + + :host { + align-items: center; + height: 2px; + overflow-x: hidden; + border-radius: ${borderRadiusMedium}; + } + + :host([thickness='large']), + :host([thickness='large']) .progress, + :host([thickness='large']) .determinate { + height: 4px; + } + + :host([shape='square']), + :host([shape='square']) .progress, + :host([shape='square']) .determinate { + border-radius: 0; + } + + :host([validation-state='error']) .determinate { + background-color: ${colorPaletteRedBackground3}; + } + + :host([validation-state='error']) .indeterminate-indicator-1, + :host([validation-state='error']) .indeterminate-indicator-2 { + background: linear-gradient( + to right, + ${colorPaletteRedBackground2} 0%, + ${colorPaletteRedBackground3} 50%, + ${colorPaletteRedBackground2} + ); + } + + :host([validation-state='warning']) .determinate { + background-color: ${colorPaletteDarkOrangeBackground3}; + } + + :host([validation-state='warning']) .indeterminate-indicator-1, + :host([validation-state='warning']) .indeterminate-indicator-2 { + background: linear-gradient( + to right, + ${colorPaletteDarkOrangeBackground2} 0%, + ${colorPaletteDarkOrangeBackground3} 50%, + ${colorPaletteDarkOrangeBackground2} + ); + } + + :host([validation-state='success']) .determinate { + background-color: ${colorPaletteGreenBackground3}; + } + + :host([validation-state='success']) .indeterminate-indicator-1, + :host([validation-state='success']) .indeterminate-indicator-2 { + background: linear-gradient( + to right, + ${colorPaletteGreenBackground2} 0%, + ${colorPaletteGreenBackground3} 50%, + ${colorPaletteGreenBackground2} + ); + } + + .progress { + background-color: ${colorNeutralBackground6}; + border-radius: ${borderRadiusMedium}; + width: 100%; + height: 2px; + display: flex; + align-items: center; + position: relative; + } + + .determinate { + background-color: ${colorCompoundBrandBackground}; + border-radius: ${borderRadiusMedium}; + height: 2px; + transition: all 0.2s ease-in-out; + display: flex; + } + + .indeterminate-indicator-1 { + position: absolute; + opacity: 0; + height: 100%; + background: linear-gradient( + to right, + ${colorBrandBackground2} 0%, + ${colorCompoundBrandBackground} 50%, + ${colorBrandBackground2} + ); + border-radius: ${borderRadiusMedium}; + animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); + width: 40%; + animation: indeterminate-1 3s infinite; + } + + .indeterminate-indicator-2 { + position: absolute; + opacity: 0; + height: 100%; + background: linear-gradient( + to right, + ${colorBrandBackground2} 0%, + ${colorCompoundBrandBackground} 50%, + ${colorBrandBackground2} + ); + border-radius: ${borderRadiusMedium}; + animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); + width: 60%; + animation: indeterminate-2 3s infinite; + } + + @keyframes indeterminate-1 { + 0% { + opacity: 1; + transform: translateX(-100%); + } + 70% { + opacity: 1; + transform: translateX(300%); + } + 70.01% { + opacity: 0; + } + 100% { + opacity: 0; + transform: translateX(300%); + } + } + @keyframes indeterminate-2 { + 0% { + opacity: 0; + transform: translateX(-150%); + } + 29.99% { + opacity: 0; + } + 30% { + opacity: 1; + transform: translateX(-150%); + } + 100% { + transform: translateX(166.66%); + opacity: 1; + } + } +`; diff --git a/packages/web-components/src/progress-bar/progress-bar.template.ts b/packages/web-components/src/progress-bar/progress-bar.template.ts new file mode 100644 index 0000000000000..acf300205766e --- /dev/null +++ b/packages/web-components/src/progress-bar/progress-bar.template.ts @@ -0,0 +1,8 @@ +import type { ElementViewTemplate } from '@microsoft/fast-element'; +import { progressTemplate } from '@microsoft/fast-foundation'; +import type { ProgressBar } from './progress-bar.js'; + +export const template: ElementViewTemplate = progressTemplate({ + indeterminateIndicator1: ``, +}); diff --git a/packages/web-components/src/progress-bar/progress-bar.ts b/packages/web-components/src/progress-bar/progress-bar.ts new file mode 100644 index 0000000000000..aff1a3e153638 --- /dev/null +++ b/packages/web-components/src/progress-bar/progress-bar.ts @@ -0,0 +1,37 @@ +import { attr } from '@microsoft/fast-element'; +import { FASTProgress } from '@microsoft/fast-foundation'; +import type { ProgressBarShape, ProgressBarThickness, ProgressBarValidationState } from './progress-bar.options.js'; + +/** + * The base class used for constructing a fluent-progress-bar custom element + * @public + */ +export class ProgressBar extends FASTProgress { + /** + * The thickness of the progress bar + * + * @public + * @remarks + * HTML Attribute: thickness + */ + @attr + public thickness: ProgressBarThickness; + + /** + * The shape of the progress bar + * @public + * @remarks + * HTML Attribute: shape + */ + @attr + public shape: ProgressBarShape; + + /** + * The validation state of the progress bar + * @public + * @remarks + * HTML Attribute: validation-state + */ + @attr({ attribute: 'validation-state' }) + public validationState: ProgressBarValidationState | null; +} From 2ec905c52a9b648505c495803f9b9a0ebf8dabd6 Mon Sep 17 00:00:00 2001 From: Martin Hochel Date: Wed, 25 Jan 2023 16:13:04 +0100 Subject: [PATCH 012/203] chore(web-components): run manually bump to fix failed CI release (#26498) * chore: run manually bump to fix failed CI release * generate changefile --- ...-06188225-69da-4cf6-918c-932a9ceab1b3.json | 7 -- ...-0b247950-52cb-4f3a-a1c3-9455ef090098.json | 7 -- ...-19128575-ce2e-40b1-8a3b-8334eb585f40.json | 7 -- ...-25e8f64c-845e-401f-a7f8-c9472a5720df.json | 7 -- ...-7d0424dc-fe77-4d05-b911-295ca60d04fd.json | 7 -- ...925986c6-b42e-4db6-a621-44ff55110a4f.json} | 2 +- ...-974b7e3c-cb82-4399-8daf-f58a9a1b23ed.json | 7 -- ...-a9829849-1747-4588-aadf-da70207d0cf0.json | 7 -- ...-d423d05a-1b1e-422f-ab9a-afc288197681.json | 7 -- packages/web-components/CHANGELOG.json | 65 +++++++++++++++++++ packages/web-components/CHANGELOG.md | 14 +++- packages/web-components/package.json | 2 +- 12 files changed, 80 insertions(+), 59 deletions(-) delete mode 100644 change/@fluentui-web-components-06188225-69da-4cf6-918c-932a9ceab1b3.json delete mode 100644 change/@fluentui-web-components-0b247950-52cb-4f3a-a1c3-9455ef090098.json delete mode 100644 change/@fluentui-web-components-19128575-ce2e-40b1-8a3b-8334eb585f40.json delete mode 100644 change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json delete mode 100644 change/@fluentui-web-components-7d0424dc-fe77-4d05-b911-295ca60d04fd.json rename change/{@fluentui-web-components-06a3ebaf-3485-4ea9-a024-ff17305e1f88.json => @fluentui-web-components-925986c6-b42e-4db6-a621-44ff55110a4f.json} (67%) delete mode 100644 change/@fluentui-web-components-974b7e3c-cb82-4399-8daf-f58a9a1b23ed.json delete mode 100644 change/@fluentui-web-components-a9829849-1747-4588-aadf-da70207d0cf0.json delete mode 100644 change/@fluentui-web-components-d423d05a-1b1e-422f-ab9a-afc288197681.json diff --git a/change/@fluentui-web-components-06188225-69da-4cf6-918c-932a9ceab1b3.json b/change/@fluentui-web-components-06188225-69da-4cf6-918c-932a9ceab1b3.json deleted file mode 100644 index 4e872c1571b2d..0000000000000 --- a/change/@fluentui-web-components-06188225-69da-4cf6-918c-932a9ceab1b3.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "add text as a new component", - "packageName": "@fluentui/web-components", - "email": "chhol@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-0b247950-52cb-4f3a-a1c3-9455ef090098.json b/change/@fluentui-web-components-0b247950-52cb-4f3a-a1c3-9455ef090098.json deleted file mode 100644 index 58b7bdb89f803..0000000000000 --- a/change/@fluentui-web-components-0b247950-52cb-4f3a-a1c3-9455ef090098.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "chore(web-components): resolve invalid webpack test regex on windows", - "packageName": "@fluentui/web-components", - "email": "martinhochel@microsoft.com", - "dependentChangeType": "none" -} diff --git a/change/@fluentui-web-components-19128575-ce2e-40b1-8a3b-8334eb585f40.json b/change/@fluentui-web-components-19128575-ce2e-40b1-8a3b-8334eb585f40.json deleted file mode 100644 index 870dde0ba9b23..0000000000000 --- a/change/@fluentui-web-components-19128575-ce2e-40b1-8a3b-8334eb585f40.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "update clean file to .cjs and ensure rimraf is in dependency tree", - "packageName": "@fluentui/web-components", - "email": "chhol@microsoft.com", - "dependentChangeType": "none" -} diff --git a/change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json b/change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json deleted file mode 100644 index 094c23a891496..0000000000000 --- a/change/@fluentui-web-components-25e8f64c-845e-401f-a7f8-c9472a5720df.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "add badge and counter badge as new components", - "packageName": "@fluentui/web-components", - "email": "chhol@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-7d0424dc-fe77-4d05-b911-295ca60d04fd.json b/change/@fluentui-web-components-7d0424dc-fe77-4d05-b911-295ca60d04fd.json deleted file mode 100644 index a203b8bda0502..0000000000000 --- a/change/@fluentui-web-components-7d0424dc-fe77-4d05-b911-295ca60d04fd.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "Add initial theme", - "packageName": "@fluentui/web-components", - "email": "miroslav.stastny@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-06a3ebaf-3485-4ea9-a024-ff17305e1f88.json b/change/@fluentui-web-components-925986c6-b42e-4db6-a621-44ff55110a4f.json similarity index 67% rename from change/@fluentui-web-components-06a3ebaf-3485-4ea9-a024-ff17305e1f88.json rename to change/@fluentui-web-components-925986c6-b42e-4db6-a621-44ff55110a4f.json index c2cb4822582aa..d922af3fc8d08 100644 --- a/change/@fluentui-web-components-06a3ebaf-3485-4ea9-a024-ff17305e1f88.json +++ b/change/@fluentui-web-components-925986c6-b42e-4db6-a621-44ff55110a4f.json @@ -1,6 +1,6 @@ { "type": "none", - "comment": "chore: bump web-components to 3.0.0-alpha.0", + "comment": "chore: run manually bump to fix failed CI release", "packageName": "@fluentui/web-components", "email": "martinhochel@microsoft.com", "dependentChangeType": "none" diff --git a/change/@fluentui-web-components-974b7e3c-cb82-4399-8daf-f58a9a1b23ed.json b/change/@fluentui-web-components-974b7e3c-cb82-4399-8daf-f58a9a1b23ed.json deleted file mode 100644 index 9581a88f06183..0000000000000 --- a/change/@fluentui-web-components-974b7e3c-cb82-4399-8daf-f58a9a1b23ed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "chore: setup typescript 4.7 for web-components package", - "packageName": "@fluentui/web-components", - "email": "martinhochel@microsoft.com", - "dependentChangeType": "none" -} diff --git a/change/@fluentui-web-components-a9829849-1747-4588-aadf-da70207d0cf0.json b/change/@fluentui-web-components-a9829849-1747-4588-aadf-da70207d0cf0.json deleted file mode 100644 index d088a43d438a5..0000000000000 --- a/change/@fluentui-web-components-a9829849-1747-4588-aadf-da70207d0cf0.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "Reset web-components for v3 development", - "packageName": "@fluentui/web-components", - "email": "miroslav.stastny@microsoft.com", - "dependentChangeType": "none" -} diff --git a/change/@fluentui-web-components-d423d05a-1b1e-422f-ab9a-afc288197681.json b/change/@fluentui-web-components-d423d05a-1b1e-422f-ab9a-afc288197681.json deleted file mode 100644 index cd6c5c717b627..0000000000000 --- a/change/@fluentui-web-components-d423d05a-1b1e-422f-ab9a-afc288197681.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "add progressbar as new component", - "packageName": "@fluentui/web-components", - "email": "ryan@ryanmerrill.net", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 5ec4f66b5f724..26bf0db8c5491 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,71 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Wed, 25 Jan 2023 14:49:08 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.1", + "version": "3.0.0-alpha.1", + "comments": { + "prerelease": [ + { + "author": "ryan@ryanmerrill.net", + "package": "@fluentui/web-components", + "commit": "1322f3f962e8a850fe104cc2ba9b12b2bc2f2842", + "comment": "add progressbar as new component" + }, + { + "author": "miroslav.stastny@microsoft.com", + "package": "@fluentui/web-components", + "commit": "6de62a46eafd74b968ec913901729b3f7284dc7a", + "comment": "Add initial theme" + }, + { + "author": "chhol@microsoft.com", + "package": "@fluentui/web-components", + "commit": "eead74fee07339f998615fe34d8f847d0f63af6e", + "comment": "add badge and counter badge as new components" + }, + { + "author": "chhol@microsoft.com", + "package": "@fluentui/web-components", + "commit": "5e3ba35835c0a5487b574ea58a51cccd67b5fa8c", + "comment": "add text as a new component" + } + ], + "none": [ + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/web-components", + "commit": "7c94cbd46051ea57bba4e8885c86e89967bb412c", + "comment": "chore: setup typescript 4.7 for web-components package" + }, + { + "author": "miroslav.stastny@microsoft.com", + "package": "@fluentui/web-components", + "commit": "cd42ab4f8aa11c7ac134538193dc8dc4a01ca0f3", + "comment": "Reset web-components for v3 development" + }, + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/web-components", + "commit": "7f15428e8fb2c3cfbfe8e555978bfa66f74f8fd8", + "comment": "chore: bump web-components to 3.0.0-alpha.0" + }, + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/web-components", + "commit": "9b29aada3dba8f929530ddc1b4b64e869d5fffd4", + "comment": "chore(web-components): resolve invalid webpack test regex on windows" + }, + { + "author": "chhol@microsoft.com", + "package": "@fluentui/web-components", + "commit": "be3d30fcbe222be34b02a554e948d14bb2d730df", + "comment": "update clean file to .cjs and ensure rimraf is in dependency tree" + } + ] + } + }, { "date": "Wed, 10 Apr 2024 07:28:55 GMT", "tag": "@fluentui/web-components_v2.6.1", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index aed229c328106..1d9754b56e02a 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,21 @@ # Change Log - @fluentui/web-components -This log was last generated on Wed, 10 Apr 2024 07:28:55 GMT and should not be manually modified. +This log was last generated on Wed, 25 Jan 2023 14:49:08 GMT and should not be manually modified. +## [3.0.0-alpha.1](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.1) + +Wed, 25 Jan 2023 14:49:08 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v2.5.8..@fluentui/web-components_v3.0.0-alpha.1) + +### Changes + +- add progressbar as new component ([PR #26329](https://github.com/microsoft/fluentui/pull/26329) by ryan@ryanmerrill.net) +- Add initial theme ([PR #25660](https://github.com/microsoft/fluentui/pull/25660) by miroslav.stastny@microsoft.com) +- add badge and counter badge as new components ([PR #26357](https://github.com/microsoft/fluentui/pull/26357) by chhol@microsoft.com) +- add text as a new component ([PR #26090](https://github.com/microsoft/fluentui/pull/26090) by chhol@microsoft.com) + ## [2.6.1](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v2.6.1) Wed, 10 Apr 2024 07:28:55 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index ce1b78ab89936..e273ef47749f4 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.0", + "version": "3.0.0-alpha.1", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 2141a973ae96786b9992b834e8f394b296719be7 Mon Sep 17 00:00:00 2001 From: Miroslav Stastny Date: Wed, 25 Jan 2023 17:17:34 +0100 Subject: [PATCH 013/203] feat(web-components): export theme (#26500) * feat: export theme * change file --- ...-cd25bca5-3470-4f00-b462-08403e27845d.json | 7 + packages/web-components/docs/api-report.md | 1142 +++++++++++++++++ packages/web-components/src/index.ts | 2 + 3 files changed, 1151 insertions(+) create mode 100644 change/@fluentui-web-components-cd25bca5-3470-4f00-b462-08403e27845d.json diff --git a/change/@fluentui-web-components-cd25bca5-3470-4f00-b462-08403e27845d.json b/change/@fluentui-web-components-cd25bca5-3470-4f00-b462-08403e27845d.json new file mode 100644 index 0000000000000..3876e0f9b6880 --- /dev/null +++ b/change/@fluentui-web-components-cd25bca5-3470-4f00-b462-08403e27845d.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat: export theme", + "packageName": "@fluentui/web-components", + "email": "miroslav.stastny@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/docs/api-report.md b/packages/web-components/docs/api-report.md index 42d325f15e064..482ea6f2b5a68 100644 --- a/packages/web-components/docs/api-report.md +++ b/packages/web-components/docs/api-report.md @@ -4,6 +4,7 @@ ```ts +import { CSSDesignToken } from '@microsoft/fast-foundation'; import { ElementStyles } from '@microsoft/fast-element'; import { ElementViewTemplate } from '@microsoft/fast-element'; import { FASTElement } from '@microsoft/fast-element'; @@ -12,6 +13,7 @@ import { FASTProgress } from '@microsoft/fast-foundation'; import { StartEnd } from '@microsoft/fast-foundation'; import { StartEndOptions } from '@microsoft/fast-foundation'; import { StaticallyComposableHTML } from '@microsoft/fast-foundation'; +import type { Theme } from '@fluentui/tokens'; import { ValuesOf } from '@microsoft/fast-foundation'; // Warning: (ae-internal-mixed-release-tag) Mixed release tags are not allowed for "Badge" because one of its declarations is marked as @internal @@ -93,6 +95,900 @@ export const BadgeStyles: ElementStyles; // @public (undocumented) export const BadgeTemplate: ElementViewTemplate; +// @public (undocumented) +export const borderRadiusCircular: CSSDesignToken; + +// @public (undocumented) +export const borderRadiusLarge: CSSDesignToken; + +// @public (undocumented) +export const borderRadiusMedium: CSSDesignToken; + +// @public (undocumented) +export const borderRadiusNone: CSSDesignToken; + +// @public (undocumented) +export const borderRadiusSmall: CSSDesignToken; + +// @public (undocumented) +export const borderRadiusXLarge: CSSDesignToken; + +// @public (undocumented) +export const colorBackgroundOverlay: CSSDesignToken; + +// @public (undocumented) +export const colorBrandBackground: CSSDesignToken; + +// @public (undocumented) +export const colorBrandBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorBrandBackgroundHover: CSSDesignToken; + +// @public (undocumented) +export const colorBrandBackgroundInverted: CSSDesignToken; + +// @public (undocumented) +export const colorBrandBackgroundInvertedHover: CSSDesignToken; + +// @public (undocumented) +export const colorBrandBackgroundInvertedPressed: CSSDesignToken; + +// @public (undocumented) +export const colorBrandBackgroundInvertedSelected: CSSDesignToken; + +// @public (undocumented) +export const colorBrandBackgroundPressed: CSSDesignToken; + +// @public (undocumented) +export const colorBrandBackgroundSelected: CSSDesignToken; + +// @public (undocumented) +export const colorBrandBackgroundStatic: CSSDesignToken; + +// @public (undocumented) +export const colorBrandForeground1: CSSDesignToken; + +// @public (undocumented) +export const colorBrandForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorBrandForegroundInverted: CSSDesignToken; + +// @public (undocumented) +export const colorBrandForegroundInvertedHover: CSSDesignToken; + +// @public (undocumented) +export const colorBrandForegroundInvertedPressed: CSSDesignToken; + +// @public (undocumented) +export const colorBrandForegroundLink: CSSDesignToken; + +// @public (undocumented) +export const colorBrandForegroundLinkHover: CSSDesignToken; + +// @public (undocumented) +export const colorBrandForegroundLinkPressed: CSSDesignToken; + +// @public (undocumented) +export const colorBrandForegroundLinkSelected: CSSDesignToken; + +// @public (undocumented) +export const colorBrandForegroundOnLight: CSSDesignToken; + +// @public (undocumented) +export const colorBrandForegroundOnLightHover: CSSDesignToken; + +// @public (undocumented) +export const colorBrandForegroundOnLightPressed: CSSDesignToken; + +// @public (undocumented) +export const colorBrandForegroundOnLightSelected: CSSDesignToken; + +// @public (undocumented) +export const colorBrandShadowAmbient: CSSDesignToken; + +// @public (undocumented) +export const colorBrandShadowKey: CSSDesignToken; + +// @public (undocumented) +export const colorBrandStroke1: CSSDesignToken; + +// @public (undocumented) +export const colorBrandStroke2: CSSDesignToken; + +// @public (undocumented) +export const colorCompoundBrandBackground: CSSDesignToken; + +// @public (undocumented) +export const colorCompoundBrandBackgroundHover: CSSDesignToken; + +// @public (undocumented) +export const colorCompoundBrandBackgroundPressed: CSSDesignToken; + +// @public (undocumented) +export const colorCompoundBrandForeground1: CSSDesignToken; + +// @public (undocumented) +export const colorCompoundBrandForeground1Hover: CSSDesignToken; + +// @public (undocumented) +export const colorCompoundBrandForeground1Pressed: CSSDesignToken; + +// @public (undocumented) +export const colorCompoundBrandStroke: CSSDesignToken; + +// @public (undocumented) +export const colorCompoundBrandStrokeHover: CSSDesignToken; + +// @public (undocumented) +export const colorCompoundBrandStrokePressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground1: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground1Hover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground1Pressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground1Selected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground2Hover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground2Pressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground2Selected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground3: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground3Hover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground3Pressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground3Selected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground4: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground4Hover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground4Pressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground4Selected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground5: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground5Hover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground5Pressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground5Selected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackground6: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackgroundDisabled: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackgroundInverted: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackgroundInvertedDisabled: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralBackgroundStatic: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground1: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground1Hover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground1Pressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground1Selected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground1Static: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground2BrandHover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground2BrandPressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground2BrandSelected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground2Hover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground2Link: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground2LinkHover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground2LinkPressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground2LinkSelected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground2Pressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground2Selected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground3: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground3BrandHover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground3BrandPressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground3BrandSelected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground3Hover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground3Pressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground3Selected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForeground4: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForegroundDisabled: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForegroundInverted: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForegroundInverted2: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForegroundInvertedDisabled: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForegroundInvertedHover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForegroundInvertedLink: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForegroundInvertedLinkHover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForegroundInvertedLinkPressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForegroundInvertedLinkSelected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForegroundInvertedPressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForegroundInvertedSelected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForegroundOnBrand: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralForegroundStaticInverted: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralShadowAmbient: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralShadowAmbientDarker: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralShadowAmbientLighter: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralShadowKey: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralShadowKeyDarker: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralShadowKeyLighter: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStencil1: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStencil2: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStroke1: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStroke1Hover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStroke1Pressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStroke1Selected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStroke2: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStroke3: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStrokeAccessible: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStrokeAccessibleHover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStrokeAccessiblePressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStrokeAccessibleSelected: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStrokeDisabled: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStrokeInvertedDisabled: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStrokeOnBrand: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStrokeOnBrand2: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStrokeOnBrand2Hover: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStrokeOnBrand2Pressed: CSSDesignToken; + +// @public (undocumented) +export const colorNeutralStrokeOnBrand2Selected: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteAnchorBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteAnchorBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteAnchorForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBeigeBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBeigeBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBeigeForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBerryBackground1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBerryBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBerryBackground3: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBerryBorder1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBerryBorder2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBerryBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBerryForeground1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBerryForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBerryForeground3: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBlueBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBlueBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBlueForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBrassBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBrassBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBrassForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBrownBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBrownBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteBrownForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteCornflowerBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteCornflowerBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteCornflowerForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteCranberryBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteCranberryBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteCranberryForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkGreenBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkGreenBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkGreenForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkOrangeBackground1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkOrangeBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkOrangeBackground3: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkOrangeBorder1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkOrangeBorder2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkOrangeBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkOrangeForeground1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkOrangeForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkOrangeForeground3: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkRedBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkRedBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteDarkRedForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteForestBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteForestBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteForestForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGoldBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGoldBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGoldForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGrapeBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGrapeBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGrapeForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGreenBackground1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGreenBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGreenBackground3: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGreenBorder1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGreenBorder2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGreenBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGreenForeground1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGreenForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteGreenForeground3: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLavenderBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLavenderBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLavenderForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLightGreenBackground1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLightGreenBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLightGreenBackground3: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLightGreenBorder1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLightGreenBorder2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLightGreenBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLightGreenForeground1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLightGreenForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLightGreenForeground3: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLightTealBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLightTealBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLightTealForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLilacBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLilacBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteLilacForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMagentaBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMagentaBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMagentaForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMarigoldBackground1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMarigoldBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMarigoldBackground3: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMarigoldBorder1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMarigoldBorder2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMarigoldBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMarigoldForeground1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMarigoldForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMarigoldForeground3: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMinkBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMinkBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteMinkForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteNavyBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteNavyBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteNavyForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePeachBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePeachBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePeachForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePinkBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePinkBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePinkForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePlatinumBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePlatinumBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePlatinumForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePlumBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePlumBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePlumForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePumpkinBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePumpkinBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePumpkinForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePurpleBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePurpleBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPalettePurpleForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteRedBackground1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteRedBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteRedBackground3: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteRedBorder1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteRedBorder2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteRedBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteRedForeground1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteRedForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteRedForeground3: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteRoyalBlueBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteRoyalBlueBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteRoyalBlueForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteSeafoamBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteSeafoamBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteSeafoamForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteSteelBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteSteelBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteSteelForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteTealBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteTealBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteTealForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteYellowBackground1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteYellowBackground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteYellowBackground3: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteYellowBorder1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteYellowBorder2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteYellowBorderActive: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteYellowForeground1: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteYellowForeground2: CSSDesignToken; + +// @public (undocumented) +export const colorPaletteYellowForeground3: CSSDesignToken; + +// @public (undocumented) +export const colorScrollbarOverlay: CSSDesignToken; + +// @public (undocumented) +export const colorStrokeFocus1: CSSDesignToken; + +// @public (undocumented) +export const colorStrokeFocus2: CSSDesignToken; + +// @public (undocumented) +export const colorSubtleBackground: CSSDesignToken; + +// @public (undocumented) +export const colorSubtleBackgroundHover: CSSDesignToken; + +// @public (undocumented) +export const colorSubtleBackgroundInverted: CSSDesignToken; + +// @public (undocumented) +export const colorSubtleBackgroundInvertedHover: CSSDesignToken; + +// @public (undocumented) +export const colorSubtleBackgroundInvertedPressed: CSSDesignToken; + +// @public (undocumented) +export const colorSubtleBackgroundInvertedSelected: CSSDesignToken; + +// @public (undocumented) +export const colorSubtleBackgroundLightAlphaHover: CSSDesignToken; + +// @public (undocumented) +export const colorSubtleBackgroundLightAlphaPressed: CSSDesignToken; + +// @public (undocumented) +export const colorSubtleBackgroundLightAlphaSelected: CSSDesignToken; + +// @public (undocumented) +export const colorSubtleBackgroundPressed: CSSDesignToken; + +// @public (undocumented) +export const colorSubtleBackgroundSelected: CSSDesignToken; + +// @public (undocumented) +export const colorTransparentBackground: CSSDesignToken; + +// @public (undocumented) +export const colorTransparentBackgroundHover: CSSDesignToken; + +// @public (undocumented) +export const colorTransparentBackgroundPressed: CSSDesignToken; + +// @public (undocumented) +export const colorTransparentBackgroundSelected: CSSDesignToken; + +// @public (undocumented) +export const colorTransparentStroke: CSSDesignToken; + +// @public (undocumented) +export const colorTransparentStrokeDisabled: CSSDesignToken; + +// @public (undocumented) +export const colorTransparentStrokeInteractive: CSSDesignToken; + // Warning: (ae-internal-mixed-release-tag) Mixed release tags are not allowed for "CounterBadge" because one of its declarations is marked as @internal // // @public @@ -177,6 +1073,135 @@ export const CounterBadgeStyles: ElementStyles; // @public export const CounterBadgeTemplate: ElementViewTemplate; +// @public (undocumented) +export const curveAccelerateMax: CSSDesignToken; + +// @public (undocumented) +export const curveAccelerateMid: CSSDesignToken; + +// @public (undocumented) +export const curveAccelerateMin: CSSDesignToken; + +// @public (undocumented) +export const curveDecelerateMax: CSSDesignToken; + +// @public (undocumented) +export const curveDecelerateMid: CSSDesignToken; + +// @public (undocumented) +export const curveDecelerateMin: CSSDesignToken; + +// @public (undocumented) +export const curveEasyEase: CSSDesignToken; + +// @public (undocumented) +export const curveEasyEaseMax: CSSDesignToken; + +// @public (undocumented) +export const curveLinear: CSSDesignToken; + +// @public (undocumented) +export const durationFast: CSSDesignToken; + +// @public (undocumented) +export const durationFaster: CSSDesignToken; + +// @public (undocumented) +export const durationNormal: CSSDesignToken; + +// @public (undocumented) +export const durationSlow: CSSDesignToken; + +// @public (undocumented) +export const durationSlower: CSSDesignToken; + +// @public (undocumented) +export const durationUltraFast: CSSDesignToken; + +// @public (undocumented) +export const durationUltraSlow: CSSDesignToken; + +// @public (undocumented) +export const fontFamilyBase: CSSDesignToken; + +// @public (undocumented) +export const fontFamilyMonospace: CSSDesignToken; + +// @public (undocumented) +export const fontFamilyNumeric: CSSDesignToken; + +// @public (undocumented) +export const fontSizeBase100: CSSDesignToken; + +// @public (undocumented) +export const fontSizeBase200: CSSDesignToken; + +// @public (undocumented) +export const fontSizeBase300: CSSDesignToken; + +// @public (undocumented) +export const fontSizeBase400: CSSDesignToken; + +// @public (undocumented) +export const fontSizeBase500: CSSDesignToken; + +// @public (undocumented) +export const fontSizeBase600: CSSDesignToken; + +// @public (undocumented) +export const fontSizeHero1000: CSSDesignToken; + +// @public (undocumented) +export const fontSizeHero700: CSSDesignToken; + +// @public (undocumented) +export const fontSizeHero800: CSSDesignToken; + +// @public (undocumented) +export const fontSizeHero900: CSSDesignToken; + +// @public (undocumented) +export const fontWeightBold: CSSDesignToken; + +// @public (undocumented) +export const fontWeightMedium: CSSDesignToken; + +// @public (undocumented) +export const fontWeightRegular: CSSDesignToken; + +// @public (undocumented) +export const fontWeightSemibold: CSSDesignToken; + +// @public (undocumented) +export const lineHeightBase100: CSSDesignToken; + +// @public (undocumented) +export const lineHeightBase200: CSSDesignToken; + +// @public (undocumented) +export const lineHeightBase300: CSSDesignToken; + +// @public (undocumented) +export const lineHeightBase400: CSSDesignToken; + +// @public (undocumented) +export const lineHeightBase500: CSSDesignToken; + +// @public (undocumented) +export const lineHeightBase600: CSSDesignToken; + +// @public (undocumented) +export const lineHeightHero1000: CSSDesignToken; + +// @public (undocumented) +export const lineHeightHero700: CSSDesignToken; + +// @public (undocumented) +export const lineHeightHero800: CSSDesignToken; + +// @public (undocumented) +export const lineHeightHero900: CSSDesignToken; + // @public export class ProgressBar extends FASTProgress { shape: ProgressBarShape; @@ -221,6 +1246,123 @@ export const ProgressBarValidationState: { // @public export type ProgressBarValidationState = ValuesOf; +// @public +export const setTheme: (theme: Theme) => void; + +// @public (undocumented) +export const shadow16: CSSDesignToken; + +// @public (undocumented) +export const shadow16Brand: CSSDesignToken; + +// @public (undocumented) +export const shadow2: CSSDesignToken; + +// @public (undocumented) +export const shadow28: CSSDesignToken; + +// @public (undocumented) +export const shadow28Brand: CSSDesignToken; + +// @public (undocumented) +export const shadow2Brand: CSSDesignToken; + +// @public (undocumented) +export const shadow4: CSSDesignToken; + +// @public (undocumented) +export const shadow4Brand: CSSDesignToken; + +// @public (undocumented) +export const shadow64: CSSDesignToken; + +// @public (undocumented) +export const shadow64Brand: CSSDesignToken; + +// @public (undocumented) +export const shadow8: CSSDesignToken; + +// @public (undocumented) +export const shadow8Brand: CSSDesignToken; + +// @public (undocumented) +export const spacingHorizontalL: CSSDesignToken; + +// @public (undocumented) +export const spacingHorizontalM: CSSDesignToken; + +// @public (undocumented) +export const spacingHorizontalMNudge: CSSDesignToken; + +// @public (undocumented) +export const spacingHorizontalNone: CSSDesignToken; + +// @public (undocumented) +export const spacingHorizontalS: CSSDesignToken; + +// @public (undocumented) +export const spacingHorizontalSNudge: CSSDesignToken; + +// @public (undocumented) +export const spacingHorizontalXL: CSSDesignToken; + +// @public (undocumented) +export const spacingHorizontalXS: CSSDesignToken; + +// @public (undocumented) +export const spacingHorizontalXXL: CSSDesignToken; + +// @public (undocumented) +export const spacingHorizontalXXS: CSSDesignToken; + +// @public (undocumented) +export const spacingHorizontalXXXL: CSSDesignToken; + +// @public (undocumented) +export const spacingVerticalL: CSSDesignToken; + +// @public (undocumented) +export const spacingVerticalM: CSSDesignToken; + +// @public (undocumented) +export const spacingVerticalMNudge: CSSDesignToken; + +// @public (undocumented) +export const spacingVerticalNone: CSSDesignToken; + +// @public (undocumented) +export const spacingVerticalS: CSSDesignToken; + +// @public (undocumented) +export const spacingVerticalSNudge: CSSDesignToken; + +// @public (undocumented) +export const spacingVerticalXL: CSSDesignToken; + +// @public (undocumented) +export const spacingVerticalXS: CSSDesignToken; + +// @public (undocumented) +export const spacingVerticalXXL: CSSDesignToken; + +// @public (undocumented) +export const spacingVerticalXXS: CSSDesignToken; + +// @public (undocumented) +export const spacingVerticalXXXL: CSSDesignToken; + +// @public (undocumented) +export const strokeWidthThick: CSSDesignToken; + +// @public (undocumented) +export const strokeWidthThicker: CSSDesignToken; + +// @public (undocumented) +export const strokeWidthThickest: CSSDesignToken; + +// @public (undocumented) +export const strokeWidthThin: CSSDesignToken; + // @public class Text_2 extends FASTElement { align: TextAlign; diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index 0feb1f29f22f0..e0440b0f08d5b 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -2,3 +2,5 @@ export * from './badge/index.js'; export * from './counter-badge/index.js'; export * from './progress-bar/index.js'; export * from './text/index.js'; + +export * from './theme/index.js'; From 5f99781a80456d672ac725a09b51251df09305ba Mon Sep 17 00:00:00 2001 From: Martin Hochel Date: Wed, 25 Jan 2023 19:56:17 +0100 Subject: [PATCH 014/203] ci: fix github pushes auth for release (#26502) * ci: fix github pushes auth for release * chore(web-components): run manually bump to fix failed CI release * generate changefile --- azure-pipelines.release.web-components.yml | 3 ++- ...-cd25bca5-3470-4f00-b462-08403e27845d.json | 7 ------ ...f4ad3059-b14e-4647-bef9-7f9458e4f9ab.json} | 2 +- packages/web-components/CHANGELOG.json | 23 +++++++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++- packages/web-components/package.json | 2 +- 6 files changed, 37 insertions(+), 11 deletions(-) delete mode 100644 change/@fluentui-web-components-cd25bca5-3470-4f00-b462-08403e27845d.json rename change/{@fluentui-web-components-925986c6-b42e-4db6-a621-44ff55110a4f.json => @fluentui-web-components-f4ad3059-b14e-4647-bef9-7f9458e4f9ab.json} (63%) diff --git a/azure-pipelines.release.web-components.yml b/azure-pipelines.release.web-components.yml index 855074ffa1c5f..9085ba2edfe27 100644 --- a/azure-pipelines.release.web-components.yml +++ b/azure-pipelines.release.web-components.yml @@ -40,7 +40,8 @@ jobs: - script: | git config user.name "Fluent UI Build" git config user.email "fluentui-internal@service.microsoft.com" - displayName: Configure git user (used by beachball) + git remote set-url origin https://$(githubUser):$(githubPAT)@github.com/microsoft/fluentui.git + displayName: Authenticate git for pushes - task: Bash@3 inputs: diff --git a/change/@fluentui-web-components-cd25bca5-3470-4f00-b462-08403e27845d.json b/change/@fluentui-web-components-cd25bca5-3470-4f00-b462-08403e27845d.json deleted file mode 100644 index 3876e0f9b6880..0000000000000 --- a/change/@fluentui-web-components-cd25bca5-3470-4f00-b462-08403e27845d.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat: export theme", - "packageName": "@fluentui/web-components", - "email": "miroslav.stastny@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-925986c6-b42e-4db6-a621-44ff55110a4f.json b/change/@fluentui-web-components-f4ad3059-b14e-4647-bef9-7f9458e4f9ab.json similarity index 63% rename from change/@fluentui-web-components-925986c6-b42e-4db6-a621-44ff55110a4f.json rename to change/@fluentui-web-components-f4ad3059-b14e-4647-bef9-7f9458e4f9ab.json index d922af3fc8d08..64ebb9a55e305 100644 --- a/change/@fluentui-web-components-925986c6-b42e-4db6-a621-44ff55110a4f.json +++ b/change/@fluentui-web-components-f4ad3059-b14e-4647-bef9-7f9458e4f9ab.json @@ -1,6 +1,6 @@ { "type": "none", - "comment": "chore: run manually bump to fix failed CI release", + "comment": "chore(web-components): run manually bump to fix failed CI release", "packageName": "@fluentui/web-components", "email": "martinhochel@microsoft.com", "dependentChangeType": "none" diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 26bf0db8c5491..36a97f7abb457 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,29 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Wed, 25 Jan 2023 17:42:30 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.2", + "version": "3.0.0-alpha.2", + "comments": { + "prerelease": [ + { + "author": "miroslav.stastny@microsoft.com", + "package": "@fluentui/web-components", + "commit": "68de783e80c71173a717c758680a63bf9c7e8c78", + "comment": "feat: export theme" + } + ], + "none": [ + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/web-components", + "commit": "c5b3031ada2f788ef0a36185024f4c10c16143d6", + "comment": "chore: run manually bump to fix failed CI release" + } + ] + } + }, { "date": "Wed, 25 Jan 2023 14:49:08 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.1", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index 1d9754b56e02a..e0d9ac51ddf91 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Wed, 25 Jan 2023 14:49:08 GMT and should not be manually modified. +This log was last generated on Wed, 25 Jan 2023 17:42:30 GMT and should not be manually modified. +## [3.0.0-alpha.2](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.2) + +Wed, 25 Jan 2023 17:42:30 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.1..@fluentui/web-components_v3.0.0-alpha.2) + +### Changes + +- feat: export theme ([PR #26500](https://github.com/microsoft/fluentui/pull/26500) by miroslav.stastny@microsoft.com) + ## [3.0.0-alpha.1](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.1) Wed, 25 Jan 2023 14:49:08 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index e273ef47749f4..7d602c3f90c62 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.1", + "version": "3.0.0-alpha.2", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From bd3775e376220ef6b846bdadcde3bd92fb9a7117 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Thu, 26 Jan 2023 04:19:04 +0000 Subject: [PATCH 015/203] applying package updates --- ...ents-f4ad3059-b14e-4647-bef9-7f9458e4f9ab.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 change/@fluentui-web-components-f4ad3059-b14e-4647-bef9-7f9458e4f9ab.json diff --git a/change/@fluentui-web-components-f4ad3059-b14e-4647-bef9-7f9458e4f9ab.json b/change/@fluentui-web-components-f4ad3059-b14e-4647-bef9-7f9458e4f9ab.json deleted file mode 100644 index 64ebb9a55e305..0000000000000 --- a/change/@fluentui-web-components-f4ad3059-b14e-4647-bef9-7f9458e4f9ab.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "chore(web-components): run manually bump to fix failed CI release", - "packageName": "@fluentui/web-components", - "email": "martinhochel@microsoft.com", - "dependentChangeType": "none" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 36a97f7abb457..e54f7ca50649c 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Thu, 26 Jan 2023 04:18:59 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.2", + "version": "3.0.0-alpha.2", + "comments": { + "none": [ + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/web-components", + "commit": "1949a66866dca51e82530efdedbb3d455880d614", + "comment": "chore(web-components): run manually bump to fix failed CI release" + } + ] + } + }, { "date": "Wed, 25 Jan 2023 17:42:30 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.2", From 43a09d23c26ef7f7223bcfa6c568d96509d7b9b2 Mon Sep 17 00:00:00 2001 From: Martin Hochel Date: Fri, 3 Feb 2023 14:32:26 +0100 Subject: [PATCH 016/203] ci: setup web-components docsite CI/CD (#26629) * chore(web-components): turn of storybook telemetry * ci: setup web-components docsite CI/CD * generate change-file --- .../azure-static-web-apps-deploy.yml | 50 +++++++++++++++++++ ...-b1d83acd-4849-4848-b056-d97f03b7c37c.json | 7 +++ packages/web-components/.storybook/main.cjs | 4 +- 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/azure-static-web-apps-deploy.yml create mode 100644 change/@fluentui-web-components-b1d83acd-4849-4848-b056-d97f03b7c37c.json diff --git a/.github/workflows/azure-static-web-apps-deploy.yml b/.github/workflows/azure-static-web-apps-deploy.yml new file mode 100644 index 0000000000000..40e7827568dfd --- /dev/null +++ b/.github/workflows/azure-static-web-apps-deploy.yml @@ -0,0 +1,50 @@ +name: Azure Static Web Apps CI/CD + +on: + push: + branches: + - web-components-v3 + paths: + - packages/web-components/* + pull_request: + types: [opened, synchronize, reopened, closed] + branches: + - web-components-v3 + paths: + - packages/web-components/* + +permissions: + contents: read + pull-requests: write + +jobs: + build_and_deploy_job: + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') + runs-on: ubuntu-latest + name: Build and Deploy Job + steps: + - uses: actions/checkout@v2 + + - name: Build and Deploy Job + id: builddeploy + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.WEB_COMPONENTS_AZURE_STATIC_WEB_APPS_API_TOKEN }} + repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for GitHub integrations (i.e. PR comments) + action: 'upload' + app_build_command: 'yarn workspace @fluentui/web-components build-storybook' + app_location: '/packages/web-components' # App source code path relative to repository root + output_location: 'dist/storybook' # Built app content directory, relative to app_location - optional + skip_api_build: true + + close_pull_request_job: + if: github.event_name == 'pull_request' && github.event.action == 'closed' + runs-on: ubuntu-latest + name: Close Pull Request Job + steps: + - name: Close Pull Request + id: closepullrequest + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.WEB_COMPONENTS_AZURE_STATIC_WEB_APPS_API_TOKEN }} + action: 'close' diff --git a/change/@fluentui-web-components-b1d83acd-4849-4848-b056-d97f03b7c37c.json b/change/@fluentui-web-components-b1d83acd-4849-4848-b056-d97f03b7c37c.json new file mode 100644 index 0000000000000..c1d34f9cc3666 --- /dev/null +++ b/change/@fluentui-web-components-b1d83acd-4849-4848-b056-d97f03b7c37c.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "ci: setup web-components docsite CI/CD", + "packageName": "@fluentui/web-components", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/packages/web-components/.storybook/main.cjs b/packages/web-components/.storybook/main.cjs index 681fab30011f0..cfe2fcd503e19 100644 --- a/packages/web-components/.storybook/main.cjs +++ b/packages/web-components/.storybook/main.cjs @@ -2,7 +2,7 @@ const CircularDependencyPlugin = require('circular-dependency-plugin'); const tsBin = require.resolve('typescript'); -module.exports = { +module.exports = /** @type {Omit} */ ({ stories: ['../src/**/*.stories.@(ts|mdx)'], staticDirs: ['../public'], core: { @@ -61,4 +61,4 @@ module.exports = { return config; }, -}; +}); From 5b8bb47b73f10fdab44f14b2c37a45980f7d2c52 Mon Sep 17 00:00:00 2001 From: ling1726 Date: Fri, 3 Feb 2023 16:37:40 +0100 Subject: [PATCH 017/203] Update azure-static-web-apps-deploy.yml (#26632) * Update azure-static-web-apps-deploy.yml * Update and rename azure-static-web-apps-deploy.yml to azure-storage-web-components.yml * Update azure-storage-web-components.yml * Create azure-static-web-apps-deploy.yml --- .../azure-storage-web-components.yml | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/azure-storage-web-components.yml diff --git a/.github/workflows/azure-storage-web-components.yml b/.github/workflows/azure-storage-web-components.yml new file mode 100644 index 0000000000000..4b11931a5060e --- /dev/null +++ b/.github/workflows/azure-storage-web-components.yml @@ -0,0 +1,35 @@ +name: Azure Static Web Apps CI/CD + +on: + workflow_dispatch: + +permissions: + contents: read + pull-requests: write + +jobs: + build_and_deploy_job: + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') + runs-on: ubuntu-latest + name: Build and Deploy Job + steps: + - uses: actions/checkout@v2 + + - name: Setup Node.js environment + uses: actions/setup-node@v3.6.0 + with: + node-version: 14.x + + - run: yarn + + - run: yarn workspace @fluentui/web-components build-storybook + + - uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Azure CLI Action + uses: Azure/cli@v1.0.7 + with: + # Specify the script here + inlineScript: az storage blob upload-batch --account-name webcomponentsdocsite --auth-mode key -d '$web' -s ./packages/web-components/dist/storybook From c2f09b4fd97ebbafc0f1b752883ce3989cd69f2c Mon Sep 17 00:00:00 2001 From: ling1726 Date: Fri, 3 Feb 2023 16:40:04 +0100 Subject: [PATCH 018/203] Update azure-storage-web-components.yml (#26633) --- .github/workflows/azure-storage-web-components.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/azure-storage-web-components.yml b/.github/workflows/azure-storage-web-components.yml index 4b11931a5060e..c15a704a00558 100644 --- a/.github/workflows/azure-storage-web-components.yml +++ b/.github/workflows/azure-storage-web-components.yml @@ -1,4 +1,4 @@ -name: Azure Static Web Apps CI/CD +name: Azure storage publish web components on: workflow_dispatch: From 4f0fbaa0f02af75302d5cdeb191a6b0d95a9bfee Mon Sep 17 00:00:00 2001 From: ling1726 Date: Fri, 3 Feb 2023 16:49:12 +0100 Subject: [PATCH 019/203] Update azure-storage-web-components.yml (#26635) --- .github/workflows/azure-storage-web-components.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/azure-storage-web-components.yml b/.github/workflows/azure-storage-web-components.yml index c15a704a00558..45400b2c37d0f 100644 --- a/.github/workflows/azure-storage-web-components.yml +++ b/.github/workflows/azure-storage-web-components.yml @@ -2,6 +2,9 @@ name: Azure storage publish web components on: workflow_dispatch: + push: + branches: + - web-components-v3 permissions: contents: read From 70d1e2a15a26bb2dadb55b9e851e1f2c5f7dd6d5 Mon Sep 17 00:00:00 2001 From: Martin Hochel Date: Fri, 3 Feb 2023 17:25:42 +0100 Subject: [PATCH 020/203] ci: remove pull_request workflows from ASW WC (#26636) --- .../azure-static-web-apps-deploy.yml | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/.github/workflows/azure-static-web-apps-deploy.yml b/.github/workflows/azure-static-web-apps-deploy.yml index 40e7827568dfd..0d1a36770d84f 100644 --- a/.github/workflows/azure-static-web-apps-deploy.yml +++ b/.github/workflows/azure-static-web-apps-deploy.yml @@ -1,4 +1,4 @@ -name: Azure Static Web Apps CI/CD +name: Azure Static Web Apps web components on: push: @@ -6,19 +6,12 @@ on: - web-components-v3 paths: - packages/web-components/* - pull_request: - types: [opened, synchronize, reopened, closed] - branches: - - web-components-v3 - paths: - - packages/web-components/* permissions: contents: read - pull-requests: write jobs: - build_and_deploy_job: + build_and_deploy: if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') runs-on: ubuntu-latest name: Build and Deploy Job @@ -36,15 +29,3 @@ jobs: app_location: '/packages/web-components' # App source code path relative to repository root output_location: 'dist/storybook' # Built app content directory, relative to app_location - optional skip_api_build: true - - close_pull_request_job: - if: github.event_name == 'pull_request' && github.event.action == 'closed' - runs-on: ubuntu-latest - name: Close Pull Request Job - steps: - - name: Close Pull Request - id: closepullrequest - uses: Azure/static-web-apps-deploy@v1 - with: - azure_static_web_apps_api_token: ${{ secrets.WEB_COMPONENTS_AZURE_STATIC_WEB_APPS_API_TOKEN }} - action: 'close' From 31a88b79d89cb7e609a39cc5d04f1851bbbdd147 Mon Sep 17 00:00:00 2001 From: Martin Hochel Date: Fri, 3 Feb 2023 17:26:12 +0100 Subject: [PATCH 021/203] style: format yml workflow (#26634) --- .github/workflows/azure-storage-web-components.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/azure-storage-web-components.yml b/.github/workflows/azure-storage-web-components.yml index 45400b2c37d0f..622342226db38 100644 --- a/.github/workflows/azure-storage-web-components.yml +++ b/.github/workflows/azure-storage-web-components.yml @@ -1,7 +1,8 @@ name: Azure storage publish web components on: - workflow_dispatch: + # NOTE: manual workflows work only if workflow exists in default branch - which is not our case 👀 + # workflow_dispatch: push: branches: - web-components-v3 @@ -17,12 +18,12 @@ jobs: name: Build and Deploy Job steps: - uses: actions/checkout@v2 - + - name: Setup Node.js environment uses: actions/setup-node@v3.6.0 with: node-version: 14.x - + - run: yarn - run: yarn workspace @fluentui/web-components build-storybook From 80570b0f813b463ee63cbf9e562bd86888b750cd Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Mon, 6 Feb 2023 04:20:35 +0000 Subject: [PATCH 022/203] applying package updates --- ...ents-b1d83acd-4849-4848-b056-d97f03b7c37c.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 change/@fluentui-web-components-b1d83acd-4849-4848-b056-d97f03b7c37c.json diff --git a/change/@fluentui-web-components-b1d83acd-4849-4848-b056-d97f03b7c37c.json b/change/@fluentui-web-components-b1d83acd-4849-4848-b056-d97f03b7c37c.json deleted file mode 100644 index c1d34f9cc3666..0000000000000 --- a/change/@fluentui-web-components-b1d83acd-4849-4848-b056-d97f03b7c37c.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "ci: setup web-components docsite CI/CD", - "packageName": "@fluentui/web-components", - "email": "martinhochel@microsoft.com", - "dependentChangeType": "none" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index e54f7ca50649c..6de450f879c02 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Mon, 06 Feb 2023 04:20:29 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.2", + "version": "3.0.0-alpha.2", + "comments": { + "none": [ + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/web-components", + "commit": "dcf643c51586968fa700b83eb1982866e6cfe946", + "comment": "ci: setup web-components docsite CI/CD" + } + ] + } + }, { "date": "Thu, 26 Jan 2023 04:18:59 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.2", From b1e022ae5456a5640dbf632dd00c4be0fdf7d520 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Mon, 13 Feb 2023 04:21:44 +0000 Subject: [PATCH 023/203] applying package updates --- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 6de450f879c02..e7c840f291c2d 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Mon, 13 Feb 2023 04:21:38 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.2", + "version": "3.0.0-alpha.2", + "comments": { + "none": [ + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/web-components", + "commit": "5745de0ab6ab860f905c33d4430b857b8a72f27f", + "comment": "style: fix formatting in files that were silently passed previously" + } + ] + } + }, { "date": "Mon, 06 Feb 2023 04:20:29 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.2", From b9851d092c1eeb06214ffb619f9c433fc08de8af Mon Sep 17 00:00:00 2001 From: Ryan Merrill Date: Tue, 14 Feb 2023 18:23:24 +0000 Subject: [PATCH 024/203] Adds basic implementation of Spinner component (#26392) * Adds basic implementation of Spinner component * Adds inverted Story to Spinner * Cleans up some typos * Generates API report * Adds change file * Removes kebab-case for key in Spinner in favor of camelCase; Adds spinner export to package.json; Properly comments spinner options with type docs * Address feedback in PR * Minor typo cleanup * Rebuilds --- ...-b6b8fdad-d432-4c23-871e-ff051099582f.json | 7 ++ packages/web-components/docs/api-report.md | 39 ++++++++ packages/web-components/package.json | 4 + packages/web-components/src/index.ts | 1 + packages/web-components/src/spinner/define.ts | 4 + packages/web-components/src/spinner/index.ts | 5 + .../src/spinner/spinner.definition.ts | 19 ++++ .../src/spinner/spinner.options.ts | 36 +++++++ .../src/spinner/spinner.stories.ts | 53 ++++++++++ .../src/spinner/spinner.styles.ts | 96 +++++++++++++++++++ .../src/spinner/spinner.template.ts | 24 +++++ .../web-components/src/spinner/spinner.ts | 30 ++++++ 12 files changed, 318 insertions(+) create mode 100644 change/@fluentui-web-components-b6b8fdad-d432-4c23-871e-ff051099582f.json create mode 100644 packages/web-components/src/spinner/define.ts create mode 100644 packages/web-components/src/spinner/index.ts create mode 100644 packages/web-components/src/spinner/spinner.definition.ts create mode 100644 packages/web-components/src/spinner/spinner.options.ts create mode 100644 packages/web-components/src/spinner/spinner.stories.ts create mode 100644 packages/web-components/src/spinner/spinner.styles.ts create mode 100644 packages/web-components/src/spinner/spinner.template.ts create mode 100644 packages/web-components/src/spinner/spinner.ts diff --git a/change/@fluentui-web-components-b6b8fdad-d432-4c23-871e-ff051099582f.json b/change/@fluentui-web-components-b6b8fdad-d432-4c23-871e-ff051099582f.json new file mode 100644 index 0000000000000..3293939cda595 --- /dev/null +++ b/change/@fluentui-web-components-b6b8fdad-d432-4c23-871e-ff051099582f.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Adds Spinner as a web component", + "packageName": "@fluentui/web-components", + "email": "ryan@ryanmerrill.net", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/docs/api-report.md b/packages/web-components/docs/api-report.md index 482ea6f2b5a68..aa4ae9ca2ea41 100644 --- a/packages/web-components/docs/api-report.md +++ b/packages/web-components/docs/api-report.md @@ -10,6 +10,7 @@ import { ElementViewTemplate } from '@microsoft/fast-element'; import { FASTElement } from '@microsoft/fast-element'; import { FASTElementDefinition } from '@microsoft/fast-element'; import { FASTProgress } from '@microsoft/fast-foundation'; +import { FASTProgressRing } from '@microsoft/fast-foundation'; import { StartEnd } from '@microsoft/fast-foundation'; import { StartEndOptions } from '@microsoft/fast-foundation'; import { StaticallyComposableHTML } from '@microsoft/fast-foundation'; @@ -1351,6 +1352,44 @@ export const spacingVerticalXXS: CSSDesignToken; // @public (undocumented) export const spacingVerticalXXXL: CSSDesignToken; +// @public +export class Spinner extends FASTProgressRing { + appearance: SpinnerAppearance; + size: SpinnerSize; +} + +// @public +export const SpinnerAppearance: { + readonly primary: "primary"; + readonly inverted: "inverted"; +}; + +// @public +export type SpinnerAppearance = ValuesOf; + +// @public +export const SpinnerDefinition: FASTElementDefinition; + +// @public +export const SpinnerSize: { + readonly tiny: "tiny"; + readonly extraSmall: "extra-small"; + readonly small: "small"; + readonly medium: "medium"; + readonly large: "large"; + readonly extraLarge: "extra-large"; + readonly huge: "huge"; +}; + +// @public +export type SpinnerSize = ValuesOf; + +// @public (undocumented) +export const SpinnerStyles: ElementStyles; + +// @public (undocumented) +export const SpinnerTemplate: ElementViewTemplate; + // @public (undocumented) export const strokeWidthThick: CSSDesignToken; diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 7d602c3f90c62..8c93c23967132 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -39,6 +39,10 @@ "./progress-bar": { "types": "./dist/esm/progress-bar/define.d.ts", "default": "./dist/esm/progress-bar/define.js" + }, + "./spinner": { + "types": "./dist/esm/spinner/define.d.ts", + "default": "./dist/esm/spinner/define.js" } }, "scripts": { diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index e0440b0f08d5b..78cf3190790a6 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -1,6 +1,7 @@ export * from './badge/index.js'; export * from './counter-badge/index.js'; export * from './progress-bar/index.js'; +export * from './spinner/index.js'; export * from './text/index.js'; export * from './theme/index.js'; diff --git a/packages/web-components/src/spinner/define.ts b/packages/web-components/src/spinner/define.ts new file mode 100644 index 0000000000000..8bca7912b206c --- /dev/null +++ b/packages/web-components/src/spinner/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './spinner.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/spinner/index.ts b/packages/web-components/src/spinner/index.ts new file mode 100644 index 0000000000000..2a6c2db892f33 --- /dev/null +++ b/packages/web-components/src/spinner/index.ts @@ -0,0 +1,5 @@ +export * from './spinner.js'; +export * from './spinner.options.js'; +export { template as SpinnerTemplate } from './spinner.template.js'; +export { styles as SpinnerStyles } from './spinner.styles.js'; +export { definition as SpinnerDefinition } from './spinner.definition.js'; diff --git a/packages/web-components/src/spinner/spinner.definition.ts b/packages/web-components/src/spinner/spinner.definition.ts new file mode 100644 index 0000000000000..edb459e352855 --- /dev/null +++ b/packages/web-components/src/spinner/spinner.definition.ts @@ -0,0 +1,19 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Spinner } from './spinner.js'; +import { styles } from './spinner.styles.js'; +import { template } from './spinner.template.js'; + +/** + * The Fluent Spinner Element. Implements {@link @microsoft/fast-foundation#ProgressRing }, + * {@link @microsoft/fast-foundation#progress-ringTemplate} + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = Spinner.compose({ + name: `${FluentDesignSystem.prefix}-spinner`, + template, + styles, +}); diff --git a/packages/web-components/src/spinner/spinner.options.ts b/packages/web-components/src/spinner/spinner.options.ts new file mode 100644 index 0000000000000..5d1c888833552 --- /dev/null +++ b/packages/web-components/src/spinner/spinner.options.ts @@ -0,0 +1,36 @@ +import { ValuesOf } from '@microsoft/fast-foundation'; + +/** + * SpinnerAppearance constants + * @public + */ +export const SpinnerAppearance = { + primary: 'primary', + inverted: 'inverted', +} as const; + +/** + * A Spinner's appearance can be either primary or inverted + * @public + */ +export type SpinnerAppearance = ValuesOf; + +/** + * SpinnerSize constants + * @public + */ +export const SpinnerSize = { + tiny: 'tiny', + extraSmall: 'extra-small', + small: 'small', + medium: 'medium', + large: 'large', + extraLarge: 'extra-large', + huge: 'huge', +} as const; + +/** + * A Spinner's size can be either small, tiny, extra-small, medium, large, extra-large, or huge + * @public + */ +export type SpinnerSize = ValuesOf; diff --git a/packages/web-components/src/spinner/spinner.stories.ts b/packages/web-components/src/spinner/spinner.stories.ts new file mode 100644 index 0000000000000..e160b592207ab --- /dev/null +++ b/packages/web-components/src/spinner/spinner.stories.ts @@ -0,0 +1,53 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../__test__/helpers.js'; +import { SpinnerAppearance, SpinnerSize } from './spinner.options.js'; +import './define.js'; + +type SpinnerStoryArgs = Args; +type SpinnerStoryMeta = Meta; + +const storyTemplate = html` + x.appearance} size=${x => x.size}> +`; + +export default { + title: 'Components/Spinner', + argTypes: { + appearance: { + description: 'The appearance of the spinner', + table: { + defaultValue: { summary: 'primary' }, + }, + control: { + type: 'select', + options: Object.values(SpinnerAppearance), + }, + defaultValue: 'primary', + }, + size: { + description: 'The size of the spinner', + table: { + defaultValue: { summary: 'medium' }, + }, + control: { + type: 'select', + options: Object.values(SpinnerSize), + }, + defaultValue: 'medium', + }, + }, + parameters: { + status: { + type: 'experimental', + }, + }, +} as SpinnerStoryMeta; + +export const Spinner = renderComponent(storyTemplate).bind({}); + +export const SpinnerInverted = renderComponent(html` +
+ +
+`); diff --git a/packages/web-components/src/spinner/spinner.styles.ts b/packages/web-components/src/spinner/spinner.styles.ts new file mode 100644 index 0000000000000..c4061520382f1 --- /dev/null +++ b/packages/web-components/src/spinner/spinner.styles.ts @@ -0,0 +1,96 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { colorBrandStroke1, colorBrandStroke2, colorNeutralStrokeOnBrand2 } from '../theme/design-tokens.js'; + +export const styles = css` + ${display('flex')} + + :host { + display: flex; + align-items: center; + height: 32px; + width: 32px; + } + :host([size='tiny']) { + height: 20px; + width: 20px; + } + :host([size='extra-small']) { + height: 24px; + width: 24px; + } + :host([size='small']) { + height: 28px; + width: 28px; + } + :host([size='large']) { + height: 36px; + width: 36px; + } + :host([size='extra-large']) { + height: 40px; + width: 40px; + } + :host([size='huge']) { + height: 44px; + width: 44px; + } + .progress { + height: 100%; + width: 100%; + } + + .background { + fill: none; + stroke: ${colorBrandStroke2}; + stroke-width: 1.5px; + } + + :host([appearance='inverted']) .background { + stroke: rgba(255, 255, 255, 0.2); + } + + .determinate { + stroke: ${colorBrandStroke1}; + fill: none; + stroke-width: 1.5px; + stroke-linecap: round; + transform-origin: 50% 50%; + transform: rotate(-90deg); + transition: all 0.2s ease-in-out; + } + + :host([appearance='inverted']) .determinite { + stroke: ${colorNeutralStrokeOnBrand2}; + } + + .indeterminate-indicator-1 { + stroke: ${colorBrandStroke1}; + fill: none; + stroke-width: 1.5px; + stroke-linecap: round; + transform-origin: 50% 50%; + transform: rotate(-90deg); + transition: all 0.2s ease-in-out; + animation: spin-infinite 3s cubic-bezier(0.53, 0.21, 0.29, 0.67) infinite; + } + + :host([appearance='inverted']) .indeterminate-indicator-1 { + stroke: ${colorNeutralStrokeOnBrand2}; + } + + @keyframes spin-infinite { + 0% { + stroke-dasharray: 0.01px 43.97px; + transform: rotate(0deg); + } + 50% { + stroke-dasharray: 21.99px 21.99px; + transform: rotate(450deg); + } + 100% { + stroke-dasharray: 0.01px 43.97px; + transform: rotate(1080deg); + } + } +`; diff --git a/packages/web-components/src/spinner/spinner.template.ts b/packages/web-components/src/spinner/spinner.template.ts new file mode 100644 index 0000000000000..473efe699a828 --- /dev/null +++ b/packages/web-components/src/spinner/spinner.template.ts @@ -0,0 +1,24 @@ +import type { ElementViewTemplate } from '@microsoft/fast-element'; +import { progressRingTemplate } from '@microsoft/fast-foundation'; +import { Spinner } from './spinner.js'; + +export const template: ElementViewTemplate = progressRingTemplate({ + indeterminateIndicator: ` + + + + + `, +}); diff --git a/packages/web-components/src/spinner/spinner.ts b/packages/web-components/src/spinner/spinner.ts new file mode 100644 index 0000000000000..75a70af5f8949 --- /dev/null +++ b/packages/web-components/src/spinner/spinner.ts @@ -0,0 +1,30 @@ +import { attr } from '@microsoft/fast-element'; +import { FASTProgressRing } from '@microsoft/fast-foundation'; +import type { SpinnerAppearance, SpinnerSize } from './spinner.options.js'; + +/** + * The base class used for constructing a fluent-spinner custom element + * @public + */ +export class Spinner extends FASTProgressRing { + /** + * The size of the spinner + * + * @public + * @default 'medium' + * @remarks + * HTML Attribute: size + */ + @attr + public size: SpinnerSize; + + /** + * The appearance of the spinner + * @public + * @default 'primary' + * @remarks + * HTML Attribute: appearance + */ + @attr + public appearance: SpinnerAppearance; +} From 4873cbc905b0fda034200a2a97186449414fc8d1 Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Tue, 14 Feb 2023 16:44:49 -0800 Subject: [PATCH 025/203] update fast element and foundation versions for wc-3 branch (#26844) * update fast element and foundation versions and update reference to extend badge options * no options export yet for badge :( --- ...s-f31a00b9-ac73-4bbf-841d-f03863621252.json | 7 +++++++ packages/web-components/package.json | 4 ++-- yarn.lock | 18 +++++++++--------- 3 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 change/@fluentui-web-components-f31a00b9-ac73-4bbf-841d-f03863621252.json diff --git a/change/@fluentui-web-components-f31a00b9-ac73-4bbf-841d-f03863621252.json b/change/@fluentui-web-components-f31a00b9-ac73-4bbf-841d-f03863621252.json new file mode 100644 index 0000000000000..3194d5b3d52cc --- /dev/null +++ b/change/@fluentui-web-components-f31a00b9-ac73-4bbf-841d-f03863621252.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "update fast element and foundation versions", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 8c93c23967132..b3acb78c31b30 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -104,8 +104,8 @@ "typescript": "4.7.4" }, "dependencies": { - "@microsoft/fast-element": "^2.0.0-beta.20", - "@microsoft/fast-foundation": "^3.0.0-alpha.24", + "@microsoft/fast-element": "^2.0.0-beta.21", + "@microsoft/fast-foundation": "^3.0.0-alpha.25", "@microsoft/fast-web-utilities": "^6.0.0", "@fluentui/tokens": "1.0.0-alpha.2", "tslib": "^2.1.0" diff --git a/yarn.lock b/yarn.lock index c3a861c0b8484..b606c143f151f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2657,18 +2657,18 @@ eslint-plugin-react "7.24.0" eslint-plugin-security "1.4.0" -"@microsoft/fast-element@^2.0.0-beta.20": - version "2.0.0-beta.20" - resolved "https://registry.yarnpkg.com/@microsoft/fast-element/-/fast-element-2.0.0-beta.20.tgz#a8b145386fc2442c3dc60f2495f54b12cab85ef5" - integrity sha512-7Ehsq1FzLUQA90rQH14Bx6C0UAtx/13Ihm+0M7zQk46vL/PVvP0t/supn5UnjtI9d/zDrM5jxaFcxYjTfW8aIA== +"@microsoft/fast-element@^2.0.0-beta.21": + version "2.0.0-beta.21" + resolved "https://registry.yarnpkg.com/@microsoft/fast-element/-/fast-element-2.0.0-beta.21.tgz#98710d92f84f3e7f204514c194cbcf3ef8a485a2" + integrity sha512-cyM7ieXW82JqgHK3Es9Gu8EvtZOjqd0adhceoibQsdU9OpJVqKbriNNGDC7+EuGkMrczo2AnIIhP3/mGQ85faQ== -"@microsoft/fast-foundation@^3.0.0-alpha.24": - version "3.0.0-alpha.24" - resolved "https://registry.yarnpkg.com/@microsoft/fast-foundation/-/fast-foundation-3.0.0-alpha.24.tgz#3b750f1fbee9f7f9ca771053c7c941ff2d69fb6c" - integrity sha512-Ln33vUNm5t//rK0UAF/GM6njJr36M/ure0NUwbifAPqYmV8l9FgnnI+IY7kWBFhn+kZLERBh5sSz2TWGgMF9lg== +"@microsoft/fast-foundation@^3.0.0-alpha.25": + version "3.0.0-alpha.25" + resolved "https://registry.yarnpkg.com/@microsoft/fast-foundation/-/fast-foundation-3.0.0-alpha.25.tgz#7098318b1e9c312085c5d7bd15dc4ce19c89f85a" + integrity sha512-W3MpIxJvF3x14yWWZFVi3BXIK9JbzksLgWaQxlEhHaSwYwUDb2yaWwXJby6ZOKZa2c7ns51rv4xGTPmvaGUwag== dependencies: "@floating-ui/dom" "^1.0.3" - "@microsoft/fast-element" "^2.0.0-beta.20" + "@microsoft/fast-element" "^2.0.0-beta.21" "@microsoft/fast-web-utilities" "^6.0.0" tabbable "^5.2.0" tslib "^2.4.0" From c996f64c90bca536e27f3e69b101ffb539610fa5 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Wed, 15 Feb 2023 04:24:59 +0000 Subject: [PATCH 026/203] applying package updates --- ...-b6b8fdad-d432-4c23-871e-ff051099582f.json | 7 ------- ...-f31a00b9-ac73-4bbf-841d-f03863621252.json | 7 ------- packages/web-components/CHANGELOG.json | 21 +++++++++++++++++++ packages/web-components/CHANGELOG.md | 12 ++++++++++- packages/web-components/package.json | 2 +- 5 files changed, 33 insertions(+), 16 deletions(-) delete mode 100644 change/@fluentui-web-components-b6b8fdad-d432-4c23-871e-ff051099582f.json delete mode 100644 change/@fluentui-web-components-f31a00b9-ac73-4bbf-841d-f03863621252.json diff --git a/change/@fluentui-web-components-b6b8fdad-d432-4c23-871e-ff051099582f.json b/change/@fluentui-web-components-b6b8fdad-d432-4c23-871e-ff051099582f.json deleted file mode 100644 index 3293939cda595..0000000000000 --- a/change/@fluentui-web-components-b6b8fdad-d432-4c23-871e-ff051099582f.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "Adds Spinner as a web component", - "packageName": "@fluentui/web-components", - "email": "ryan@ryanmerrill.net", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-f31a00b9-ac73-4bbf-841d-f03863621252.json b/change/@fluentui-web-components-f31a00b9-ac73-4bbf-841d-f03863621252.json deleted file mode 100644 index 3194d5b3d52cc..0000000000000 --- a/change/@fluentui-web-components-f31a00b9-ac73-4bbf-841d-f03863621252.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "update fast element and foundation versions", - "packageName": "@fluentui/web-components", - "email": "chhol@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index e7c840f291c2d..4508dbe691628 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,27 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Wed, 15 Feb 2023 04:24:51 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.3", + "version": "3.0.0-alpha.3", + "comments": { + "prerelease": [ + { + "author": "ryan@ryanmerrill.net", + "package": "@fluentui/web-components", + "commit": "4d959c01c7b282136e669b7c0ac0d038b9deeafe", + "comment": "Adds Spinner as a web component" + }, + { + "author": "chhol@microsoft.com", + "package": "@fluentui/web-components", + "commit": "09b44a73d3d225044af4e114d210176f7f38001a", + "comment": "update fast element and foundation versions" + } + ] + } + }, { "date": "Mon, 13 Feb 2023 04:21:38 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.2", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index e0d9ac51ddf91..653092a7fa787 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,19 @@ # Change Log - @fluentui/web-components -This log was last generated on Wed, 25 Jan 2023 17:42:30 GMT and should not be manually modified. +This log was last generated on Wed, 15 Feb 2023 04:24:51 GMT and should not be manually modified. +## [3.0.0-alpha.3](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.3) + +Wed, 15 Feb 2023 04:24:51 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.2..@fluentui/web-components_v3.0.0-alpha.3) + +### Changes + +- Adds Spinner as a web component ([PR #26392](https://github.com/microsoft/fluentui/pull/26392) by ryan@ryanmerrill.net) +- update fast element and foundation versions ([PR #26844](https://github.com/microsoft/fluentui/pull/26844) by chhol@microsoft.com) + ## [3.0.0-alpha.2](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.2) Wed, 25 Jan 2023 17:42:30 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index b3acb78c31b30..a771cb7e6b497 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.2", + "version": "3.0.0-alpha.3", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 18b7eaa4e8718323da3348870c86a2f214aafb22 Mon Sep 17 00:00:00 2001 From: Martin Hochel Date: Wed, 15 Feb 2023 11:26:56 +0100 Subject: [PATCH 027/203] chore(web-components): introduce ts-solution configs and monorepo setup/DX (#26843) * chore(web-components): implement ts path aliases setup with valid ts compilation * chore(web-components): refactor test setup and test/sb utils approach * fix(web-components): tweak npmignore to not ship non relevant assets * chore: re-generate api-report * generate change file * fixup! chore(web-components): refactor test setup and test/sb utils approach --- ...-516db34f-7e06-4348-a459-507ea3b7c881.json | 7 ++ packages/web-components/.npmignore | 8 ++- packages/web-components/.storybook/main.cjs | 20 +++++- .../web-components/.storybook/preview.mjs | 6 +- .../web-components/.storybook/tsconfig.json | 10 +++ packages/web-components/api-extractor.json | 8 +++ packages/web-components/docs/api-report.md | 7 +- packages/web-components/karma.conf.cjs | 5 +- packages/web-components/package.json | 7 +- .../web-components/public/theme-switch.ts | 2 +- packages/web-components/rollup.config.js | 3 +- .../{build/clean.cjs => scripts/clean.js} | 9 ++- packages/web-components/scripts/compile.js | 69 +++++++++++++++++++ .../web-components/scripts/setup-browser.cjs | 11 +++ .../{build => scripts}/transform-fragments.js | 0 .../src/__test__/setup-browser.cts | 6 -- .../web-components/src/badge/badge.stories.ts | 2 +- .../counter-badge/counter-badge.stories.ts | 2 +- .../src/{__test__ => }/helpers.ts | 0 .../src/progress-bar/progress-bar.stories.ts | 2 +- .../src/spinner/spinner.stories.ts | 2 +- .../web-components/src/storybook-typings.d.ts | 4 -- .../web-components/src/text/text.stories.ts | 2 +- .../web-components/storybook-typings.d.ts | 4 -- packages/web-components/tsconfig.json | 30 ++++---- packages/web-components/tsconfig.lib.json | 15 ++++ packages/web-components/tsconfig.spec.json | 9 +++ tsconfig.base.wc.json | 20 ++++++ 28 files changed, 217 insertions(+), 53 deletions(-) create mode 100644 change/@fluentui-web-components-516db34f-7e06-4348-a459-507ea3b7c881.json create mode 100644 packages/web-components/.storybook/tsconfig.json rename packages/web-components/{build/clean.cjs => scripts/clean.js} (76%) create mode 100644 packages/web-components/scripts/compile.js create mode 100644 packages/web-components/scripts/setup-browser.cjs rename packages/web-components/{build => scripts}/transform-fragments.js (100%) delete mode 100644 packages/web-components/src/__test__/setup-browser.cts rename packages/web-components/src/{__test__ => }/helpers.ts (100%) delete mode 100644 packages/web-components/src/storybook-typings.d.ts delete mode 100644 packages/web-components/storybook-typings.d.ts create mode 100644 packages/web-components/tsconfig.lib.json create mode 100644 packages/web-components/tsconfig.spec.json create mode 100644 tsconfig.base.wc.json diff --git a/change/@fluentui-web-components-516db34f-7e06-4348-a459-507ea3b7c881.json b/change/@fluentui-web-components-516db34f-7e06-4348-a459-507ea3b7c881.json new file mode 100644 index 0000000000000..d46bbfcf29cf6 --- /dev/null +++ b/change/@fluentui-web-components-516db34f-7e06-4348-a459-507ea3b7c881.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore(web-components): introduce ts-solution configs and monorepo setup/DX", + "packageName": "@fluentui/web-components", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/packages/web-components/.npmignore b/packages/web-components/.npmignore index db6d6409bd971..4283a6309c2c1 100644 --- a/packages/web-components/.npmignore +++ b/packages/web-components/.npmignore @@ -1,7 +1,6 @@ # Tests -dist/dts/__test__/ -dist/esm/__test__/ *.spec.* +*.test.* coverage/ # images @@ -10,12 +9,16 @@ images/ # Source files src/ +scripts/ + # config files .eslintignore .eslintrc.js .prettierignore .storybook tsconfig.json +tsconfig.lib.json +tsconfig.spec.json tsconfig.build.json rollup.config.json karma.conf.cjs @@ -24,6 +27,7 @@ api-extractor.json # Storybook static site dist/storybook-static/ +public/ # cache .rollupcache diff --git a/packages/web-components/.storybook/main.cjs b/packages/web-components/.storybook/main.cjs index cfe2fcd503e19..374e8c7b63d60 100644 --- a/packages/web-components/.storybook/main.cjs +++ b/packages/web-components/.storybook/main.cjs @@ -1,8 +1,15 @@ +const path = require('path'); const CircularDependencyPlugin = require('circular-dependency-plugin'); +const { TsconfigPathsPlugin } = require('tsconfig-paths-webpack-plugin'); const tsBin = require.resolve('typescript'); +const tsConfigPath = path.resolve(__dirname, '../../../tsconfig.base.wc.json'); -module.exports = /** @type {Omit} */ ({ +const tsPaths = new TsconfigPathsPlugin({ + configFile: tsConfigPath, +}); + +module.exports = /** @type {Omit} */ ({ stories: ['../src/**/*.stories.@(ts|mdx)'], staticDirs: ['../public'], core: { @@ -24,10 +31,19 @@ module.exports = /** @type {Omit { + config.resolve = config.resolve ?? {}; + config.resolve.extensions = config.resolve.extensions ?? []; + config.resolve.plugins = config.resolve.plugins ?? []; + config.module = config.module ?? {}; + config.plugins = config.plugins ?? []; + config.resolve.extensionAlias = { '.js': ['.ts', '.js'], '.mjs': ['.mts', '.mjs'], }; + config.resolve.extensions.push(...['.ts', '.js']); + config.resolve.plugins.push(tsPaths); + config.module.rules = config.module.rules ?? []; config.module.rules.push( { test: /\.([cm]?ts|tsx)$/, @@ -46,7 +62,7 @@ module.exports = /** @type {Omit; export const lineHeightHero900: CSSDesignToken; // @public -export class ProgressBar extends FASTProgress { +class ProgressBar_2 extends FASTProgress { shape: ProgressBarShape; thickness: ProgressBarThickness; validationState: ProgressBarValidationState | null; } +export { ProgressBar_2 as ProgressBar } // @public -export const ProgressBarDefinition: FASTElementDefinition; +export const ProgressBarDefinition: FASTElementDefinition; // @public export const ProgressBarShape: { @@ -1226,7 +1227,7 @@ export type ProgressBarShape = ValuesOf; export const ProgressBarStyles: ElementStyles; // @public (undocumented) -export const ProgressBarTemplate: ElementViewTemplate; +export const ProgressBarTemplate: ElementViewTemplate; // @public export const ProgressBarThickness: { diff --git a/packages/web-components/karma.conf.cjs b/packages/web-components/karma.conf.cjs index 50321485c4632..8bc390ec314b6 100644 --- a/packages/web-components/karma.conf.cjs +++ b/packages/web-components/karma.conf.cjs @@ -29,6 +29,7 @@ module.exports = function (config) { } const setup = 'setup-browser' + (config.package ? '-' + config.package : ''); + const options = { basePath, browserDisconnectTimeout: 10000, @@ -44,9 +45,9 @@ module.exports = function (config) { require('karma-chrome-launcher'), require('karma-firefox-launcher'), ], - files: [`dist/esm/__test__/${setup}.js`], + files: [`scripts/${setup}.cjs`], preprocessors: { - [`dist/esm/__test__/${setup}.cjs`]: ['webpack', 'sourcemap'], + [`scripts/${setup}.cjs`]: ['webpack', 'sourcemap'], }, webpackMiddleware: { // webpack-dev-middleware configuration diff --git a/packages/web-components/package.json b/packages/web-components/package.json index a771cb7e6b497..9042053d139d6 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -48,10 +48,11 @@ "scripts": { "tsc": "tsc", "api-extractor": "api-extractor", - "clean": "node ./build/clean.cjs dist", + "compile": "node ./scripts/compile", + "clean": "node ./scripts/clean dist", "doc": "api-extractor run --local", "doc:ci": "yarn doc", - "build": "tsc -p ./tsconfig.json && rollup -c && yarn doc", + "build": "yarn compile && rollup -c && yarn doc", "dev": "tsc -p ./tsconfig.json -w", "tdd": "yarn dev & yarn test-chrome:watch", "prepare": "yarn clean && yarn build", @@ -60,7 +61,7 @@ "format": "prettier -w 'src/**/(*.ts|*.html)' --ignore-path ../../.prettierignore", "format:check": "yarn format -c", "code-style": "yarn format:check && yarn lint", - "start": "yarn start-storybook -p 6006 --docs", + "start": "yarn start-storybook -p 6006 --docs --no-manager-cache", "start-storybook": "node node_modules/@storybook/html/bin/index", "build-storybook": "node node_modules/@storybook/html/bin/build -o ./dist/storybook --docs", "test": "yarn doc:ci && yarn test-chrome:verbose", diff --git a/packages/web-components/public/theme-switch.ts b/packages/web-components/public/theme-switch.ts index 86f4cbb264a43..705a2526a5af1 100644 --- a/packages/web-components/public/theme-switch.ts +++ b/packages/web-components/public/theme-switch.ts @@ -1,5 +1,5 @@ import { teamsDarkTheme, teamsLightTheme, webDarkTheme, webLightTheme } from '@fluentui/tokens'; -import { setTheme } from '../src/theme'; +import { setTheme } from '@fluentui/web-components'; const themes = { 'web-light': webLightTheme, diff --git a/packages/web-components/rollup.config.js b/packages/web-components/rollup.config.js index d3c02fd5ba91c..a1773719db194 100644 --- a/packages/web-components/rollup.config.js +++ b/packages/web-components/rollup.config.js @@ -4,7 +4,7 @@ import resolve from 'rollup-plugin-node-resolve'; import { terser } from 'rollup-plugin-terser'; import transformTaggedTemplate from 'rollup-plugin-transform-tagged-template'; import typescript from 'rollup-plugin-typescript2'; -import { transformCSSFragment, transformHTMLFragment } from './build/transform-fragments'; +import { transformCSSFragment, transformHTMLFragment } from './scripts/transform-fragments'; // eslint-disable-next-line no-undef const tsBin = require.resolve('typescript'); @@ -33,6 +33,7 @@ export default [ typescript({ // eslint-disable-next-line no-undef typescript: require(tsBin), + tsconfig: './tsconfig.lib.json', tsconfigOverride: { compilerOptions: { declaration: false, diff --git a/packages/web-components/build/clean.cjs b/packages/web-components/scripts/clean.js similarity index 76% rename from packages/web-components/build/clean.cjs rename to packages/web-components/scripts/clean.js index 75af0dc75b5a8..2adbc830f9e12 100644 --- a/packages/web-components/build/clean.cjs +++ b/packages/web-components/scripts/clean.js @@ -1,10 +1,13 @@ +/* eslint-disable no-undef */ /** * Utility for cleaning directories. * Usage: node build/clean.js %path% */ -const path = require('path'); -const rimraf = require('rimraf'); -const argv = require('yargs').argv; +import * as path from 'path'; +import rimraf from 'rimraf'; +import yargs from 'yargs'; + +const argv = yargs.argv; /** * All paths passed to the clean script diff --git a/packages/web-components/scripts/compile.js b/packages/web-components/scripts/compile.js new file mode 100644 index 0000000000000..85478f77ca3e9 --- /dev/null +++ b/packages/web-components/scripts/compile.js @@ -0,0 +1,69 @@ +/* eslint-disable no-undef */ +import * as path from 'path'; +import * as fs from 'fs'; +import { fileURLToPath } from 'url'; +import { execSync } from 'child_process'; +import chalk from 'chalk'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const root = path.join(__dirname, '..'); + +main(); + +function compile() { + const packageJsonPath = path.join(root, 'package.json'); + const tsConfigLibPath = path.join(root, 'tsconfig.lib.json'); + const tsConfigSpecPath = path.join(root, 'tsconfig.spec.json'); + + const tsConfigLib = JSON.parse(fs.readFileSync(tsConfigLibPath, 'utf-8')); + const tsConfigSpec = JSON.parse(fs.readFileSync(tsConfigSpecPath, 'utf-8')); + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); + + const modifiedTsConfigLib = overrideTsConfig({ ...tsConfigLib }); + const modifiedTsConfigSpec = overrideTsConfig({ ...tsConfigSpec }); + + const tempTsconfigLibPath = path.join(root, 'tsconfig.lib-generated.json'); + const tempTsconfigSpecPath = path.join(root, 'tsconfig.spec-generated.json'); + + fs.writeFileSync(tempTsconfigLibPath, JSON.stringify(modifiedTsConfigLib, null, 2), 'utf-8'); + fs.writeFileSync(tempTsconfigSpecPath, JSON.stringify(modifiedTsConfigSpec, null, 2), 'utf-8'); + + const workspaceDependencies = Object.keys(packageJson.dependencies).filter(depName => + depName.startsWith('@fluentui/'), + ); + + try { + console.log(chalk.bold(`🎬 compile:start`)); + + console.log(chalk.blueBright(`compile: building workspace dependencies: ${workspaceDependencies}`)); + execSync(`lage build --to ${workspaceDependencies}`, { stdio: 'inherit' }); + + console.log(chalk.blueBright(`compile: running tsc`)); + execSync(`tsc -p tsconfig.lib-generated.json`, { stdio: 'inherit' }); + execSync(`tsc -p tsconfig.spec-generated.json`, { stdio: 'inherit' }); + + console.log(chalk.bold(`🏁 compile:end`)); + } catch (err) { + console.error(err); + process.exit(1); + } finally { + fs.unlinkSync(tempTsconfigLibPath); + fs.unlinkSync(tempTsconfigSpecPath); + } +} + +/** + * + * @param {Record} config + */ +function overrideTsConfig(config) { + config.compilerOptions.paths = {}; + config.compilerOptions.rootDir = './src'; + return config; +} + +function main() { + compile(); +} diff --git a/packages/web-components/scripts/setup-browser.cjs b/packages/web-components/scripts/setup-browser.cjs new file mode 100644 index 0000000000000..86e98bc29b537 --- /dev/null +++ b/packages/web-components/scripts/setup-browser.cjs @@ -0,0 +1,11 @@ +/* eslint-disable no-undef */ +/** + * + * @param r {__WebpackModuleApi.RequireContext} + */ +function importAll(r) { + r.keys().forEach(r); +} + +// Explicitly add to browser test +importAll(require.context('../dist/esm', true, /\.spec\.js$/)); diff --git a/packages/web-components/build/transform-fragments.js b/packages/web-components/scripts/transform-fragments.js similarity index 100% rename from packages/web-components/build/transform-fragments.js rename to packages/web-components/scripts/transform-fragments.js diff --git a/packages/web-components/src/__test__/setup-browser.cts b/packages/web-components/src/__test__/setup-browser.cts deleted file mode 100644 index cb22e88f66c42..0000000000000 --- a/packages/web-components/src/__test__/setup-browser.cts +++ /dev/null @@ -1,6 +0,0 @@ -function importAll(r: __WebpackModuleApi.RequireContext): void { - r.keys().forEach(r); -} - -// Explicitly add to browser test -importAll(require.context('../', true, /\.spec\.js$/)); diff --git a/packages/web-components/src/badge/badge.stories.ts b/packages/web-components/src/badge/badge.stories.ts index f931eadf524be..4016ea4a14272 100644 --- a/packages/web-components/src/badge/badge.stories.ts +++ b/packages/web-components/src/badge/badge.stories.ts @@ -1,6 +1,6 @@ import { html, when } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; -import { renderComponent } from '../__test__/helpers.js'; +import { renderComponent } from '../helpers.js'; import type { Badge as FluentBadge } from './badge.js'; import { BadgeAppearance, BadgeColor, BadgeShape, BadgeSize } from './badge.options.js'; import './define.js'; diff --git a/packages/web-components/src/counter-badge/counter-badge.stories.ts b/packages/web-components/src/counter-badge/counter-badge.stories.ts index aa3011ade4622..e57d6f8097a16 100644 --- a/packages/web-components/src/counter-badge/counter-badge.stories.ts +++ b/packages/web-components/src/counter-badge/counter-badge.stories.ts @@ -1,6 +1,6 @@ import { html } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; -import { renderComponent } from '../__test__/helpers.js'; +import { renderComponent } from '../helpers.js'; import type { CounterBadge as FluentCounterBadge } from './counter-badge.js'; import { CounterBadgeAppearance, diff --git a/packages/web-components/src/__test__/helpers.ts b/packages/web-components/src/helpers.ts similarity index 100% rename from packages/web-components/src/__test__/helpers.ts rename to packages/web-components/src/helpers.ts diff --git a/packages/web-components/src/progress-bar/progress-bar.stories.ts b/packages/web-components/src/progress-bar/progress-bar.stories.ts index bd9203fff8c26..5977e4f4b382e 100644 --- a/packages/web-components/src/progress-bar/progress-bar.stories.ts +++ b/packages/web-components/src/progress-bar/progress-bar.stories.ts @@ -1,6 +1,6 @@ import { html } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; -import { renderComponent } from '../__test__/helpers.js'; +import { renderComponent } from '../helpers.js'; import type { ProgressBar as FluentProgressBar } from './progress-bar.js'; import { ProgressBarShape, ProgressBarThickness, ProgressBarValidationState } from './progress-bar.options.js'; import './define.js'; diff --git a/packages/web-components/src/spinner/spinner.stories.ts b/packages/web-components/src/spinner/spinner.stories.ts index e160b592207ab..ee05e791565e7 100644 --- a/packages/web-components/src/spinner/spinner.stories.ts +++ b/packages/web-components/src/spinner/spinner.stories.ts @@ -1,6 +1,6 @@ import { html } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; -import { renderComponent } from '../__test__/helpers.js'; +import { renderComponent } from '../helpers.js'; import { SpinnerAppearance, SpinnerSize } from './spinner.options.js'; import './define.js'; diff --git a/packages/web-components/src/storybook-typings.d.ts b/packages/web-components/src/storybook-typings.d.ts deleted file mode 100644 index 1198a9a63346d..0000000000000 --- a/packages/web-components/src/storybook-typings.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module '*.html' { - const value: string; - export default value; -} diff --git a/packages/web-components/src/text/text.stories.ts b/packages/web-components/src/text/text.stories.ts index 511c274062484..45bea65c60358 100644 --- a/packages/web-components/src/text/text.stories.ts +++ b/packages/web-components/src/text/text.stories.ts @@ -1,6 +1,6 @@ import { html } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; -import { renderComponent } from '../__test__/helpers.js'; +import { renderComponent } from '../helpers.js'; import type { Text as FluentText } from './text.js'; import './define.js'; import { TextAlign, TextFont, TextSize, TextWeight } from './text.options.js'; diff --git a/packages/web-components/storybook-typings.d.ts b/packages/web-components/storybook-typings.d.ts deleted file mode 100644 index 1198a9a63346d..0000000000000 --- a/packages/web-components/storybook-typings.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module '*.html' { - const value: string; - export default value; -} diff --git a/packages/web-components/tsconfig.json b/packages/web-components/tsconfig.json index ec8a5a0595591..5ff1a0e61b3d1 100644 --- a/packages/web-components/tsconfig.json +++ b/packages/web-components/tsconfig.json @@ -1,20 +1,22 @@ { + "extends": "../../tsconfig.base.wc.json", "compilerOptions": { - "declaration": true, - "esModuleInterop": true, + "target": "ES2019", + "module": "ESNext", "experimentalDecorators": true, "resolveJsonModule": true, - "moduleResolution": "Node16", - "declarationDir": "dist/dts", - "outDir": "dist/esm", - "strictNullChecks": true, - "target": "es2015", - "module": "ESNext", - "allowJs": true, - "skipLibCheck": true, - "importHelpers": true, - "types": ["node", "mocha", "webpack-env"], - "lib": ["DOM", "ES2015", "ES2016.Array.Include"] + "allowJs": true }, - "include": ["src"] + "files": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./.storybook/tsconfig.json" + } + ] } diff --git a/packages/web-components/tsconfig.lib.json b/packages/web-components/tsconfig.lib.json new file mode 100644 index 0000000000000..3a37340d55a22 --- /dev/null +++ b/packages/web-components/tsconfig.lib.json @@ -0,0 +1,15 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "target": "ES2019", + "module": "ESNext", + "lib": ["ESNext", "DOM"], + "declaration": true, + "declarationDir": "dist/dts", + "outDir": "dist/esm", + "importHelpers": true, + "types": [] + }, + "include": ["src"], + "exclude": ["**/*.stories.*", "**/*.test.*", "**/*.spec.*"] +} diff --git a/packages/web-components/tsconfig.spec.json b/packages/web-components/tsconfig.spec.json new file mode 100644 index 0000000000000..c1bb2d7f5e275 --- /dev/null +++ b/packages/web-components/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "ESNext", + "outDir": "dist/esm", + "types": ["mocha", "node", "webpack-env"] + }, + "include": ["src/**/*.test.*", "src/**/*.spec.*"] +} diff --git a/tsconfig.base.wc.json b/tsconfig.base.wc.json new file mode 100644 index 0000000000000..e209b3fa7f7f6 --- /dev/null +++ b/tsconfig.base.wc.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2019", + "module": "ESNext", + "moduleResolution": "Node16", + "esModuleInterop": true, + "sourceMap": true, + "strictNullChecks": true, + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true, + "pretty": true, + "typeRoots": ["node_modules/@types", "./typings"], + "rootDir": ".", + "baseUrl": ".", + "paths": { + "@fluentui/web-components": ["packages/web-components/src/index.ts"], + "@fluentui/tokens": ["packages/tokens/src/index.ts"] + } + } +} From 27dfeadc8f7f65b6217d93b3332c722324d033e4 Mon Sep 17 00:00:00 2001 From: Martin Hochel Date: Wed, 15 Feb 2023 13:54:18 +0100 Subject: [PATCH 028/203] fix(web-components): dont ship non production assets to npm registry (#26854) * fix(web-components): dont ship non production assets to npm registry * generate change file --- ...-c9bafa19-7bba-4e91-a34b-ef812e450e99.json | 7 ++++++ packages/web-components/.npmignore | 23 ++++++++++++------- packages/web-components/package.json | 10 +++----- .../web-components/src/badge/badge.stories.ts | 2 +- .../counter-badge/counter-badge.stories.ts | 2 +- .../src/{helpers.ts => helpers.stories.ts} | 0 .../src/progress-bar/progress-bar.stories.ts | 2 +- .../src/spinner/spinner.stories.ts | 2 +- .../web-components/src/text/text.stories.ts | 2 +- 9 files changed, 30 insertions(+), 20 deletions(-) create mode 100644 change/@fluentui-web-components-c9bafa19-7bba-4e91-a34b-ef812e450e99.json rename packages/web-components/src/{helpers.ts => helpers.stories.ts} (100%) diff --git a/change/@fluentui-web-components-c9bafa19-7bba-4e91-a34b-ef812e450e99.json b/change/@fluentui-web-components-c9bafa19-7bba-4e91-a34b-ef812e450e99.json new file mode 100644 index 0000000000000..6a39c8a756c5d --- /dev/null +++ b/change/@fluentui-web-components-c9bafa19-7bba-4e91-a34b-ef812e450e99.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "fix(web-components): dont ship non production assets to npm registry", + "packageName": "@fluentui/web-components", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/.npmignore b/packages/web-components/.npmignore index 4283a6309c2c1..f5729e7a6aa56 100644 --- a/packages/web-components/.npmignore +++ b/packages/web-components/.npmignore @@ -1,34 +1,41 @@ +.vscode/ + # Tests *.spec.* *.test.* coverage/ +__fixtures__ +__mocks__ +__tests__ # images images/ # Source files src/ - scripts/ # config files .eslintignore .eslintrc.js +.eslintrc.json .prettierignore -.storybook tsconfig.json -tsconfig.lib.json -tsconfig.spec.json -tsconfig.build.json +tsconfig.*.json rollup.config.json +rollup.config.js karma.conf.cjs api-extractor.json .mocharc.json -# Storybook static site -dist/storybook-static/ +# Storybook +.storybook +*.stories.* public/ +dist/storybook-static/ # cache .rollupcache -temp +temp/ +etc/ +CHANGELOG.json diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 9042053d139d6..18d87dfafbf8d 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -50,12 +50,8 @@ "api-extractor": "api-extractor", "compile": "node ./scripts/compile", "clean": "node ./scripts/clean dist", - "doc": "api-extractor run --local", - "doc:ci": "yarn doc", - "build": "yarn compile && rollup -c && yarn doc", - "dev": "tsc -p ./tsconfig.json -w", - "tdd": "yarn dev & yarn test-chrome:watch", - "prepare": "yarn clean && yarn build", + "generate-api": "api-extractor run --local", + "build": "yarn compile && rollup -c && yarn generate-api", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --ext .ts --fix", "format": "prettier -w 'src/**/(*.ts|*.html)' --ignore-path ../../.prettierignore", @@ -64,7 +60,7 @@ "start": "yarn start-storybook -p 6006 --docs --no-manager-cache", "start-storybook": "node node_modules/@storybook/html/bin/index", "build-storybook": "node node_modules/@storybook/html/bin/build -o ./dist/storybook --docs", - "test": "yarn doc:ci && yarn test-chrome:verbose", + "test": "yarn test-chrome:verbose", "test-node": "mocha --reporter min --exit dist/esm/__test__/setup-node.js './dist/esm/**/*.spec.js'", "test-node:verbose": "mocha --reporter spec --exit dist/esm/__test__/setup-node.js './dist/esm/**/*.spec.js'", "test-chrome": "karma start karma.conf.cjs --browsers=ChromeHeadlessOpt --single-run --coverage", diff --git a/packages/web-components/src/badge/badge.stories.ts b/packages/web-components/src/badge/badge.stories.ts index 4016ea4a14272..e5a74e063f633 100644 --- a/packages/web-components/src/badge/badge.stories.ts +++ b/packages/web-components/src/badge/badge.stories.ts @@ -1,6 +1,6 @@ import { html, when } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; -import { renderComponent } from '../helpers.js'; +import { renderComponent } from '../helpers.stories.js'; import type { Badge as FluentBadge } from './badge.js'; import { BadgeAppearance, BadgeColor, BadgeShape, BadgeSize } from './badge.options.js'; import './define.js'; diff --git a/packages/web-components/src/counter-badge/counter-badge.stories.ts b/packages/web-components/src/counter-badge/counter-badge.stories.ts index e57d6f8097a16..89f904621804b 100644 --- a/packages/web-components/src/counter-badge/counter-badge.stories.ts +++ b/packages/web-components/src/counter-badge/counter-badge.stories.ts @@ -1,6 +1,6 @@ import { html } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; -import { renderComponent } from '../helpers.js'; +import { renderComponent } from '../helpers.stories.js'; import type { CounterBadge as FluentCounterBadge } from './counter-badge.js'; import { CounterBadgeAppearance, diff --git a/packages/web-components/src/helpers.ts b/packages/web-components/src/helpers.stories.ts similarity index 100% rename from packages/web-components/src/helpers.ts rename to packages/web-components/src/helpers.stories.ts diff --git a/packages/web-components/src/progress-bar/progress-bar.stories.ts b/packages/web-components/src/progress-bar/progress-bar.stories.ts index 5977e4f4b382e..5d609ff780d73 100644 --- a/packages/web-components/src/progress-bar/progress-bar.stories.ts +++ b/packages/web-components/src/progress-bar/progress-bar.stories.ts @@ -1,6 +1,6 @@ import { html } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; -import { renderComponent } from '../helpers.js'; +import { renderComponent } from '../helpers.stories.js'; import type { ProgressBar as FluentProgressBar } from './progress-bar.js'; import { ProgressBarShape, ProgressBarThickness, ProgressBarValidationState } from './progress-bar.options.js'; import './define.js'; diff --git a/packages/web-components/src/spinner/spinner.stories.ts b/packages/web-components/src/spinner/spinner.stories.ts index ee05e791565e7..e9f607798711b 100644 --- a/packages/web-components/src/spinner/spinner.stories.ts +++ b/packages/web-components/src/spinner/spinner.stories.ts @@ -1,6 +1,6 @@ import { html } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; -import { renderComponent } from '../helpers.js'; +import { renderComponent } from '../helpers.stories.js'; import { SpinnerAppearance, SpinnerSize } from './spinner.options.js'; import './define.js'; diff --git a/packages/web-components/src/text/text.stories.ts b/packages/web-components/src/text/text.stories.ts index 45bea65c60358..9149311851f61 100644 --- a/packages/web-components/src/text/text.stories.ts +++ b/packages/web-components/src/text/text.stories.ts @@ -1,6 +1,6 @@ import { html } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; -import { renderComponent } from '../helpers.js'; +import { renderComponent } from '../helpers.stories.js'; import type { Text as FluentText } from './text.js'; import './define.js'; import { TextAlign, TextFont, TextSize, TextWeight } from './text.options.js'; From 1e65b278031fafa5a734a448913600035ad212f4 Mon Sep 17 00:00:00 2001 From: Justin Slone <40304143+JustSlone@users.noreply.github.com> Date: Thu, 16 Feb 2023 09:46:12 -0800 Subject: [PATCH 029/203] Manual bump of web components version (#26878) * Manual bump of web components version to match NPM 3.0.0-alpha.4 --- ...-4b3e5f7a-32b1-4a3e-9879-415aac98fc88.json | 7 ++++++ ...-516db34f-7e06-4348-a459-507ea3b7c881.json | 7 ------ ...-c9bafa19-7bba-4e91-a34b-ef812e450e99.json | 7 ------ packages/web-components/CHANGELOG.json | 23 +++++++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++- packages/web-components/package.json | 2 +- 6 files changed, 41 insertions(+), 16 deletions(-) create mode 100644 change/@fluentui-web-components-4b3e5f7a-32b1-4a3e-9879-415aac98fc88.json delete mode 100644 change/@fluentui-web-components-516db34f-7e06-4348-a459-507ea3b7c881.json delete mode 100644 change/@fluentui-web-components-c9bafa19-7bba-4e91-a34b-ef812e450e99.json diff --git a/change/@fluentui-web-components-4b3e5f7a-32b1-4a3e-9879-415aac98fc88.json b/change/@fluentui-web-components-4b3e5f7a-32b1-4a3e-9879-415aac98fc88.json new file mode 100644 index 0000000000000..cccd2223f78f2 --- /dev/null +++ b/change/@fluentui-web-components-4b3e5f7a-32b1-4a3e-9879-415aac98fc88.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: run manually to bump wc to fix failed CI release", + "packageName": "@fluentui/web-components", + "email": "jslone@microsoft.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-web-components-516db34f-7e06-4348-a459-507ea3b7c881.json b/change/@fluentui-web-components-516db34f-7e06-4348-a459-507ea3b7c881.json deleted file mode 100644 index d46bbfcf29cf6..0000000000000 --- a/change/@fluentui-web-components-516db34f-7e06-4348-a459-507ea3b7c881.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "chore(web-components): introduce ts-solution configs and monorepo setup/DX", - "packageName": "@fluentui/web-components", - "email": "martinhochel@microsoft.com", - "dependentChangeType": "none" -} diff --git a/change/@fluentui-web-components-c9bafa19-7bba-4e91-a34b-ef812e450e99.json b/change/@fluentui-web-components-c9bafa19-7bba-4e91-a34b-ef812e450e99.json deleted file mode 100644 index 6a39c8a756c5d..0000000000000 --- a/change/@fluentui-web-components-c9bafa19-7bba-4e91-a34b-ef812e450e99.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "fix(web-components): dont ship non production assets to npm registry", - "packageName": "@fluentui/web-components", - "email": "martinhochel@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 4508dbe691628..72416c7e507a9 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,29 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Thu, 16 Feb 2023 16:51:48 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.4", + "version": "3.0.0-alpha.4", + "comments": { + "none": [ + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/web-components", + "commit": "ae03f3eec389aca7e15fde295868aacd51eb1822", + "comment": "chore(web-components): introduce ts-solution configs and monorepo setup/DX" + } + ], + "prerelease": [ + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/web-components", + "commit": "226b7af089cea03d27ec722cabc73d018f263fd1", + "comment": "fix(web-components): dont ship non production assets to npm registry" + } + ] + } + }, { "date": "Wed, 15 Feb 2023 04:24:51 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.3", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index 653092a7fa787..656153860431b 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Wed, 15 Feb 2023 04:24:51 GMT and should not be manually modified. +This log was last generated on Thu, 16 Feb 2023 16:51:48 GMT and should not be manually modified. +## [3.0.0-alpha.4](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.4) + +Thu, 16 Feb 2023 16:51:48 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.3..@fluentui/web-components_v3.0.0-alpha.4) + +### Changes + +- fix(web-components): dont ship non production assets to npm registry ([PR #26854](https://github.com/microsoft/fluentui/pull/26854) by martinhochel@microsoft.com) + ## [3.0.0-alpha.3](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.3) Wed, 15 Feb 2023 04:24:51 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 18d87dfafbf8d..65c0e769ff89c 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.3", + "version": "3.0.0-alpha.4", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 63365deddb63480170555e190f1703d59b71d3bf Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Fri, 17 Feb 2023 04:19:59 +0000 Subject: [PATCH 030/203] applying package updates --- ...ents-4b3e5f7a-32b1-4a3e-9879-415aac98fc88.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 change/@fluentui-web-components-4b3e5f7a-32b1-4a3e-9879-415aac98fc88.json diff --git a/change/@fluentui-web-components-4b3e5f7a-32b1-4a3e-9879-415aac98fc88.json b/change/@fluentui-web-components-4b3e5f7a-32b1-4a3e-9879-415aac98fc88.json deleted file mode 100644 index cccd2223f78f2..0000000000000 --- a/change/@fluentui-web-components-4b3e5f7a-32b1-4a3e-9879-415aac98fc88.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "chore: run manually to bump wc to fix failed CI release", - "packageName": "@fluentui/web-components", - "email": "jslone@microsoft.com", - "dependentChangeType": "none" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 72416c7e507a9..e7a0d8a82a685 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Fri, 17 Feb 2023 04:19:53 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.4", + "version": "3.0.0-alpha.4", + "comments": { + "none": [ + { + "author": "jslone@microsoft.com", + "package": "@fluentui/web-components", + "commit": "b79b33d10cbd6015531fa943e0e6dbe7f84b9b42", + "comment": "chore: run manually to bump wc to fix failed CI release" + } + ] + } + }, { "date": "Thu, 16 Feb 2023 16:51:48 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.4", From 747479ed71beb5971d12c3369fa90cb6e56ab993 Mon Sep 17 00:00:00 2001 From: Miroslav Stastny Date: Tue, 21 Feb 2023 00:54:33 +0100 Subject: [PATCH 031/203] doc(web-components): Add storybook landing page (#26911) * docs(web-components): Add docs landing page * change file --- ...-ce5121f7-b7b0-48c8-862f-50a4684330a9.json | 7 +++++ .../web-components/.storybook/preview.mjs | 9 ++++++- .../_docs/concepts/introduction.stories.mdx | 26 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 change/@fluentui-web-components-ce5121f7-b7b0-48c8-862f-50a4684330a9.json create mode 100644 packages/web-components/src/_docs/concepts/introduction.stories.mdx diff --git a/change/@fluentui-web-components-ce5121f7-b7b0-48c8-862f-50a4684330a9.json b/change/@fluentui-web-components-ce5121f7-b7b0-48c8-862f-50a4684330a9.json new file mode 100644 index 0000000000000..df32ca69e0615 --- /dev/null +++ b/change/@fluentui-web-components-ce5121f7-b7b0-48c8-862f-50a4684330a9.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "docs: Add landing page", + "packageName": "@fluentui/web-components", + "email": "miroslav.stastny@microsoft.com", + "dependentChangeType": "none" +} diff --git a/packages/web-components/.storybook/preview.mjs b/packages/web-components/.storybook/preview.mjs index 588f4d55e3acb..ca42aab82f89b 100644 --- a/packages/web-components/.storybook/preview.mjs +++ b/packages/web-components/.storybook/preview.mjs @@ -20,8 +20,15 @@ export const parameters = { }, options: { storySort: { - order: [], method: 'alphabetical', + order: [ + 'Concepts', + [ + 'Introduction', + ], + 'Components', + 'Theme', + ], }, }, docs: { diff --git a/packages/web-components/src/_docs/concepts/introduction.stories.mdx b/packages/web-components/src/_docs/concepts/introduction.stories.mdx new file mode 100644 index 0000000000000..1c8fa5fcf8c15 --- /dev/null +++ b/packages/web-components/src/_docs/concepts/introduction.stories.mdx @@ -0,0 +1,26 @@ +import { Meta } from '@storybook/addon-docs'; +import pkg from '../../../package.json'; + + + +

+ Fluent UI Web Components v{pkg.version} +

+ +⚠️ These are not production-ready components and **should never be used in product**. This space is useful for testing new components whose APIs might change before final release. + +Microsoft's [Fluent UI Web Components](https://github.com/microsoft/fluentui/tree/master/packages/web-components) is designed to help you build Fluent web apps using extensible Web Components. The package composes the `@microsoft/fast-foundation` Web Component package and styles it with the [Fluent design language](https://github.com/microsoft/fluentui). + +### What are Web Components? + +"Web Components" is an umbrella term that refers to a collection of web standards focused on enabling the creation of custom HTML elements. Some of the standards that are under the umbrella include the ability to define new HTML tags, plug into a standard component lifecycle, encapsulate HTML rendering and CSS, parameterize CSS, skin components, and more. Each of these platform features is defined by the W3C and has shipped in every major browser today. + +### How does Fluent UI Web Components leverage Web Components? + +Fluent UI Web Components is built directly on the W3C Web Component standards, and does not create its own component model. This allows our components to function the same as built-in, native HTML elements. You do not need a framework to use Fluent UI components but you can use them in combination with any framework or library of your choice. + +### Joining the community + +Looking to get answers to questions or engage with us in realtime? Submit requests and issues on [GitHub](https://github.com/Microsoft/fast/issues/new/choose). + +We look forward to building an amazing open source community with you! From 2f2f5f3a5bfb665d5de053ad4016694e7ed4e18f Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Tue, 21 Feb 2023 04:21:42 +0000 Subject: [PATCH 032/203] applying package updates --- ...ents-ce5121f7-b7b0-48c8-862f-50a4684330a9.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 change/@fluentui-web-components-ce5121f7-b7b0-48c8-862f-50a4684330a9.json diff --git a/change/@fluentui-web-components-ce5121f7-b7b0-48c8-862f-50a4684330a9.json b/change/@fluentui-web-components-ce5121f7-b7b0-48c8-862f-50a4684330a9.json deleted file mode 100644 index df32ca69e0615..0000000000000 --- a/change/@fluentui-web-components-ce5121f7-b7b0-48c8-862f-50a4684330a9.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "docs: Add landing page", - "packageName": "@fluentui/web-components", - "email": "miroslav.stastny@microsoft.com", - "dependentChangeType": "none" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index e7a0d8a82a685..c967ddfc98bf7 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Tue, 21 Feb 2023 04:21:36 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.4", + "version": "3.0.0-alpha.4", + "comments": { + "none": [ + { + "author": "miroslav.stastny@microsoft.com", + "package": "@fluentui/web-components", + "commit": "57f2ea7f8389f1409fba6fb0697708ddf8fb05d9", + "comment": "docs: Add landing page" + } + ] + } + }, { "date": "Fri, 17 Feb 2023 04:19:53 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.4", From cfec27a9a9557171e07b9d8625c9d413f300bc04 Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Tue, 21 Feb 2023 09:14:56 -0800 Subject: [PATCH 033/203] web component accordion (#26547) * accordion and accordion item init * yarn change * updates docs * updates accordion item styles * code formatting * updates imports * adds v9 appearance sizes * updates attribute name to align with fluent v9 * adds alternative stories for accordion with custom icons * adds docs * updates storybook * updates changelog * removes dead code * removes dynamic icons from sb * removes dead code * adds accordion README * moves accordion readme to accordion directory * updates docs * updates accordion docs * updates docs * updates docs * fixes docs * fixes exports * adds display helper to styles * optimizes styles * updates html helper to use html.partial * optimizes styles * exports directly on class * removes html helper * removes arg tables from stories * sorts exports alphabetically * api report * flattens accordion componnent folders * removes comment * updates styles * optimizes styles * updates attributes * removes renaming of definition import * removes attribute syntax * adds attr * reverts api-report * removes dead code * updates styles * consolidates stories into one * updates docs * adds display helper to accordion styles --- ...-ee0dceff-c555-429c-b688-92aa40dc7f5e.json | 7 + packages/web-components/package.json | 8 + .../accordion-item.definition.ts | 19 ++ .../accordion-item/accordion-item.options.ts | 31 +++ .../accordion-item/accordion-item.styles.ts | 218 ++++++++++++++++++ .../accordion-item/accordion-item.template.ts | 40 ++++ .../src/accordion-item/accordion-item.ts | 40 ++++ .../src/accordion-item/define.ts | 4 + .../src/accordion-item/index.ts | 5 + .../web-components/src/accordion/README.md | 186 +++++++++++++++ .../src/accordion/accordion.definition.ts | 19 ++ .../src/accordion/accordion.stories.ts | 208 +++++++++++++++++ .../src/accordion/accordion.styles.ts | 11 + .../src/accordion/accordion.template.ts | 5 + .../web-components/src/accordion/accordion.ts | 7 + .../web-components/src/accordion/define.ts | 4 + .../web-components/src/accordion/index.ts | 4 + packages/web-components/src/index.ts | 2 + 18 files changed, 818 insertions(+) create mode 100644 change/@fluentui-web-components-ee0dceff-c555-429c-b688-92aa40dc7f5e.json create mode 100644 packages/web-components/src/accordion-item/accordion-item.definition.ts create mode 100644 packages/web-components/src/accordion-item/accordion-item.options.ts create mode 100644 packages/web-components/src/accordion-item/accordion-item.styles.ts create mode 100644 packages/web-components/src/accordion-item/accordion-item.template.ts create mode 100644 packages/web-components/src/accordion-item/accordion-item.ts create mode 100644 packages/web-components/src/accordion-item/define.ts create mode 100644 packages/web-components/src/accordion-item/index.ts create mode 100644 packages/web-components/src/accordion/README.md create mode 100644 packages/web-components/src/accordion/accordion.definition.ts create mode 100644 packages/web-components/src/accordion/accordion.stories.ts create mode 100644 packages/web-components/src/accordion/accordion.styles.ts create mode 100644 packages/web-components/src/accordion/accordion.template.ts create mode 100644 packages/web-components/src/accordion/accordion.ts create mode 100644 packages/web-components/src/accordion/define.ts create mode 100644 packages/web-components/src/accordion/index.ts diff --git a/change/@fluentui-web-components-ee0dceff-c555-429c-b688-92aa40dc7f5e.json b/change/@fluentui-web-components-ee0dceff-c555-429c-b688-92aa40dc7f5e.json new file mode 100644 index 0000000000000..90b77cef0e94f --- /dev/null +++ b/change/@fluentui-web-components-ee0dceff-c555-429c-b688-92aa40dc7f5e.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat(accordion): Add accordion web component", + "packageName": "@fluentui/web-components", + "email": "brianbrady@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 65c0e769ff89c..bca9d2d85006c 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -24,6 +24,14 @@ "types": "./dist/dts/index.d.ts", "default": "./dist/esm/index.js" }, + "./accordion": { + "types": "./dist/esm/accordion/define.d.ts", + "default": "./dist/esm/accordion/define.js" + }, + "./accordion-item": { + "types": "./dist/esm/accordion-item/define.d.ts", + "default": "./dist/esm/accordion-item/define.js" + }, "./badge": { "types": "./dist/esm/badge/define.d.ts", "default": "./dist/esm/badge/define.js" diff --git a/packages/web-components/src/accordion-item/accordion-item.definition.ts b/packages/web-components/src/accordion-item/accordion-item.definition.ts new file mode 100644 index 0000000000000..a922e4ed8f651 --- /dev/null +++ b/packages/web-components/src/accordion-item/accordion-item.definition.ts @@ -0,0 +1,19 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { AccordionItem } from './accordion-item.js'; +import { styles } from './accordion-item.styles.js'; +import { template } from './accordion-item.template.js'; + +/** + * The Fluent AccordionItem Element. Implements {@link @microsoft/fast-foundation#AccordionItem }, + * {@link @microsoft/fast-foundation#accordionItemTemplate} + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = AccordionItem.compose({ + name: `${FluentDesignSystem.prefix}-accordion-item`, + template, + styles, +}); diff --git a/packages/web-components/src/accordion-item/accordion-item.options.ts b/packages/web-components/src/accordion-item/accordion-item.options.ts new file mode 100644 index 0000000000000..671b2ddbf3e12 --- /dev/null +++ b/packages/web-components/src/accordion-item/accordion-item.options.ts @@ -0,0 +1,31 @@ +import { ValuesOf } from '@microsoft/fast-foundation'; + +/** + * An Accordion Item header font size can be small, medium, large, and extra-large + */ +export const AccordionItemSize = { + small: 'small', + medium: 'medium', + large: 'large', + extraLarge: 'extra-large', +} as const; + +/** + * Applies font size to accordion header + * @public + */ +export type AccordionItemSize = ValuesOf; + +/** + * An Accordion Item expand/collapse icon can appear at the start or end of the accordion + */ +export const AccordionItemExpandIconPosition = { + start: 'start', + end: 'end', +} as const; + +/** + * Applies expand/collapse icon position + * @public + */ +export type AccordionItemExpandIconPosition = ValuesOf; diff --git a/packages/web-components/src/accordion-item/accordion-item.styles.ts b/packages/web-components/src/accordion-item/accordion-item.styles.ts new file mode 100644 index 0000000000000..8ff807e33c348 --- /dev/null +++ b/packages/web-components/src/accordion-item/accordion-item.styles.ts @@ -0,0 +1,218 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + borderRadiusMedium, + borderRadiusSmall, + colorNeutralForeground1, + colorNeutralForegroundDisabled, + colorStrokeFocus1, + colorStrokeFocus2, + colorTransparentBackground, + fontFamilyBase, + fontSizeBase200, + fontSizeBase300, + fontSizeBase400, + fontSizeBase500, + fontWeightRegular, + lineHeightBase200, + lineHeightBase300, + lineHeightBase400, + lineHeightBase500, + spacingHorizontalM, + spacingHorizontalMNudge, + spacingHorizontalS, +} from '../theme/design-tokens.js'; + +export const styles = css` + ${display('block')} + + :host { + max-width: fit-content; + } + + .heading { + height: 44px; + display: grid; + position: relative; + vertical-align: middle; + padding-inline: ${spacingHorizontalM} ${spacingHorizontalMNudge}; + border-radius: ${borderRadiusMedium}; + font-family: ${fontFamilyBase}; + font-size: ${fontSizeBase300}; + font-weight: ${fontWeightRegular}; + line-height: ${lineHeightBase300}; + grid-template-columns: auto auto 1fr auto; + } + + .heading-content { + height: 100%; + display: flex; + align-items: center; + } + + .button { + box-sizing: border-box; + appearance: none; + border: none; + outline: none; + text-align: start; + cursor: pointer; + font-family: inherit; + height: 44px; + color: ${colorNeutralForeground1}; + background: ${colorTransparentBackground}; + line-height: ${lineHeightBase300}; + height: auto; + padding: 0; + font-size: inherit; + grid-column: auto / span 2; + grid-row: 1; + } + + .button::before { + content: ''; + position: absolute; + inset: 0px; + cursor: pointer; + border-radius: ${borderRadiusSmall}; + } + + .icon { + display: flex; + align-items: center; + justify-content: center; + pointer-events: none; + position: relative; + height: 100%; + padding-right: ${spacingHorizontalS}; + grid-column: 1 / span 1; + grid-row: 1; + } + + .region { + margin: 0 ${spacingHorizontalM}; + } + + ::slotted([slot='start']), + ::slotted([slot='end']) { + justify-content: center; + align-items: center; + padding-right: ${spacingHorizontalS}; + grid-column: 2 / span 1; + grid-row: 1 / span 1; + } + + button:focus-visible::after { + content: ''; + position: absolute; + inset: 0px; + cursor: pointer; + border-radius: ${borderRadiusSmall}; + outline: none; + border: 2px solid ${colorStrokeFocus1}; + box-shadow: inset 0 0 0 1px ${colorStrokeFocus2}; + } + + /* --- Disabled attr styles --- */ + + :host([disabled]) .button { + color: ${colorNeutralForegroundDisabled}; + } + :host([disabled]) svg { + filter: invert(89%) sepia(0%) saturate(569%) hue-rotate(155deg) brightness(88%) contrast(87%); + } + + /* --- Expanded attr styles --- */ + + :host([expanded]) .region { + display: block; + } + + :host([expanded]) .default-collapsed-icon, + :host([expanded]) ::slotted([slot='collapsed-icon']), + :host(:not([expanded])) .default-expanded-icon, + :host(:not([expanded])) ::slotted([slot='expanded-icon']), + :host([expanded]) ::slotted([slot='end']), + ::slotted([slot='start']), + .region { + display: none; + } + + :host([expanded]) ::slotted([slot='start']), + :host([expanded]) ::slotted([slot='expanded-icon']), + :host(:not([expanded])) ::slotted([slot='collapsed-icon']), + ::slotted([slot='end']) { + display: flex; + } + + /* --- Appearance attr styles --- */ + + .heading { + font-size: ${fontSizeBase300}; + line-height: ${lineHeightBase300}; + } + + :host([size='small']) .heading { + font-size: ${fontSizeBase200}; + line-height: ${lineHeightBase200}; + } + + :host([size='large']) .heading { + font-size: ${fontSizeBase400}; + line-height: ${lineHeightBase400}; + } + + :host([size='extra-large']) .heading { + font-size: ${fontSizeBase500}; + line-height: ${lineHeightBase500}; + } + + /* --- expand-icon-position attr styles --- */ + + :host([expand-icon-position='end']) :slotted(span[slot='start']), + :host([expand-icon-position='end']) ::slotted(span[slot='end']) { + grid-column: 1 / span 1; + grid-row: 1; + } + + :host([expand-icon-position='end']) ::slotted(span[slot='start']), + :host([expand-icon-position='end']) ::slotted(span[slot='end']) { + grid-column: 1 / span 1; + grid-row: 1; + } + + :host([expand-icon-position='end']) .icon { + grid-column: 4 / span 1; + grid-row: 1; + display: flex; + padding-left: 10px; + padding-right: 0; + } + + :host([expand-icon-position='end']) .button { + grid-column: 2 / span 3; + grid-row: 1; + } + + /* --- Block attr styles --- */ + + :host([block]) { + max-width: 100%; + } + + :host([expand-icon-position='end']) .heading { + grid-template-columns: auto auto 28px; + } + + :host([expand-icon-position='end']) .icon { + grid-column: 5 / span 1; + } + + :host([block][expand-icon-position='end']) .heading { + grid-template-columns: auto 1fr; + } + + :host([block][expand-icon-position='end']) .icon { + grid-column: 5 / span 1; + } +`; diff --git a/packages/web-components/src/accordion-item/accordion-item.template.ts b/packages/web-components/src/accordion-item/accordion-item.template.ts new file mode 100644 index 0000000000000..af59509d7ff2d --- /dev/null +++ b/packages/web-components/src/accordion-item/accordion-item.template.ts @@ -0,0 +1,40 @@ +import { ElementViewTemplate, html } from '@microsoft/fast-element'; +import { accordionItemTemplate } from '@microsoft/fast-foundation'; +import { AccordionItem } from './accordion-item.js'; + +const chevronRight20Filled = html.partial(` + +`); + +const chevronDown20Filled = html.partial(` + +`); + +/** + * The template for the fluent-accordion component. + * @public + */ +export const template: ElementViewTemplate = accordionItemTemplate({ + collapsedIcon: chevronRight20Filled, + expandedIcon: chevronDown20Filled, +}); diff --git a/packages/web-components/src/accordion-item/accordion-item.ts b/packages/web-components/src/accordion-item/accordion-item.ts new file mode 100644 index 0000000000000..0e3411cc40ae9 --- /dev/null +++ b/packages/web-components/src/accordion-item/accordion-item.ts @@ -0,0 +1,40 @@ +import { attr } from '@microsoft/fast-element'; +import { FASTAccordionItem } from '@microsoft/fast-foundation'; +import { AccordionItemExpandIconPosition, AccordionItemSize } from './accordion-item.options.js'; + +/** + * @internal + */ +export class AccordionItem extends FASTAccordionItem { + /** + * Defines accordion header font size. + * + * @public + * @default 'medium' + * @remarks + * HTML Attribute: size + */ + @attr + public size: AccordionItemSize; + + /** + * Sets the width of the focus state. + * + * @public + * @remarks + * HTML Attribute: block + */ + @attr({ mode: 'boolean' }) + public block: boolean = false; + + /** + * Sets expand and collapsed icon position. + * + * @public + * @default 'start' + * @remarks + * HTML Attribute: expandIconPosition + */ + @attr({ attribute: 'expand-icon-position' }) + public expandIconPosition: AccordionItemExpandIconPosition; +} diff --git a/packages/web-components/src/accordion-item/define.ts b/packages/web-components/src/accordion-item/define.ts new file mode 100644 index 0000000000000..97948afbe8965 --- /dev/null +++ b/packages/web-components/src/accordion-item/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './accordion-item.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/accordion-item/index.ts b/packages/web-components/src/accordion-item/index.ts new file mode 100644 index 0000000000000..14613c95835a6 --- /dev/null +++ b/packages/web-components/src/accordion-item/index.ts @@ -0,0 +1,5 @@ +export * from './accordion-item.js'; +export * from './accordion-item.options.js'; +export { styles as accordionItemStyles } from './accordion-item.styles.js'; +export { definition as accordionItemDefinition } from './accordion-item.definition.js'; +export { template as accordionItemTemplate } from './accordion-item.template.js'; diff --git a/packages/web-components/src/accordion/README.md b/packages/web-components/src/accordion/README.md new file mode 100644 index 0000000000000..7756994649bb7 --- /dev/null +++ b/packages/web-components/src/accordion/README.md @@ -0,0 +1,186 @@ +# Accordion + Accordion Item + +As defined by the [W3C](https://w3c.github.io/aria-practices/#accordion): + +> An accordion is a vertically stacked set of interactive headings that each contain a title, content snippet, or thumbnail representing a section of content. The headings function as controls that enable users to reveal or hide their associated sections of content. Accordions are commonly used to reduce the need to scroll when presenting multiple sections of content on a single page. + +
+ +## **Design Spec** + +[Link to Accordion Design Spec in Figma](https://www.figma.com/file/7X3Tgd3fTurii3FACrfhzo/Accordion?node-id=2777%3A42482&t=jHgc4PXRMQH6rPmy-0) + +
+ +## **Engineering Spec** + +Fluent WC3 Accordion extends from the FAST Accordion [FAST Accordion](https://explore.fast.design/components/fast-accordion) and is intended to be as close to the Fluent UI React 9 Menu implementation as possible. However, due to the nature of web components there will not be 100% parity between the two. + +
+ +## Class: `Accordion` + +
+ +### **Variables** + +| Name | Description | Type | +| --------------------- | ------------------------- | -------------------------------------- | +| `AccordionExpandMode` | Expand mode for Accordion | `{ single: "single", multi: "multi" }` | + +
+ +### **Fields** + +| Name | Privacy | Type | Default | Description | +| ---------------- | --------- | --------------------- | ---------- | --------------------------------------------------------------------------------------------- | +| `expandmode` | public | `AccordionExpandMode` | `multiple` | Controls the expand mode of the Accordion, either allowing single or multiple item expansion. | +| `AccordionItems` | protected | `Element[]` | + +
+ +### **Methods** + +| Name | Privacy | Description | Parameters | Return | Inherited From | +| ------------------- | ------- | ----------- | ------------------------------------------------------- | ------ | -------------- | +| `expandmodeChanged` | public | | `prev: AccordionExpandMode, next: AccordionExpandMode ` | + +
+ +### **Events** + +| Name | Type | Description | Inherited From | +| -------- | ---- | ---------------------------------------------------------- | -------------- | +| `change` | | Fires a custom 'change' event when the active item changes | + +
+ +### **Attributes** + +| Name | Field | +| ------------- | ---------- | +| `expand-mode` | expandmode | + +
+ +
+ +
+ +## Class: `AccordionItem` + +
+ +### **Variables** + +| Name | Description | Type | +| --------------------------------- | -------------------------- | --------------------------------------------------------------------------------- | +| `AccordionItemSize` | Expand modes for Accordion | `{ small: "small", medium: "medium", large: "large", extraLarge: "extra-large" }` | +| `AccordionItemExpandIconPosition` | Expand icon position | `{ start: "start", end: "end" }` | + +
+ +### **Fields** + +| Name | Privacy | Type | Default | Description | Inherited From | +| -------------------- | ------- | --------------------------------- | -------- | ---------------------------------------------------------------------------------------------- | -------------- | +| `headinglevel` | public | `1 or 2 or 3 or 4 or 5 or 6` | `2` | Configures the [level](https://www.w3.org/TR/wai-aria-1.1/#aria-level) of the heading element. | | +| `expanded` | public | `boolean` | `false` | Expands or collapses the item. | | +| `disabled` | public | `boolean` | `false` | Disables an accordion item | | +| `id` | public | `string` | | The item ID | | +| `size` | public | `AccordionItemSize` | `medium` | The font size of the AccordionItem header. | +| `block` | public | `boolean` | `true` | Sets the width of the focus state. | +| `expandIconPosition` | public | `AccordionItemExpandIconPosition` | `start` | Sets the position of the expand icon | + +
+ +### **Events** + +| Name | Type | Description | Inherited From | +| -------- | ---- | -------------------------------------------------------- | -------------- | +| `change` | | Fires a custom 'change' event when the button is invoked | | + +
+ +### **Attributes** + +| Name | Field | +| -------------------- | ------------------ | +| `heading-level` | headinglevel | +| | expanded | +| | disabled | +| | block | +| `id` | id | +| `expandIconPosition` | expandIconPosition | +| `size` | size | + +
+ +### **Slots** + +| Name | Description | +| ---------------- | -------------------------------------------------------------------------------- | +| `start` | The slot used for a presentation icon when expanded | +| `end` | The slot used for a presentation icon when collapsed | +| `heading` | Content which serves as the accordion item heading and text of the expand button | +| | The default slot for accordion item content | +| `expanded-icon` | The slot used for a custom expanded icon | +| `collapsed-icon` | The slot used for a custom collapsed icon | + +
+
+
+ +## **Accessibility** + +[W3 Accordion Spec](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/) + +
+ +### **WAI-ARIA Roles, States, and Properties** + +- `role = "button"` + - The title of each accordion header is contained in an element with role button. +- `role = "heading"` + - Each accordion header button is wrapped in an element with role heading that has a value set for aria-level that is appropriate for the information architecture of the page. +- `aria-expanded` + - If the accordion panel associated with an accordion header is visible, the header button element has aria-expanded set to true. If the panel is not visible, aria-expanded is set to false. +- `aria-controls` + - The accordion header button element has aria-controls set to the ID of the element containing the accordion panel content. +- `aria-disabled` + - If the accordion panel associated with an accordion header is visible, and if the accordion does not permit the panel to be collapsed, the header button element has aria-disabled set to true. + +
+
+
+ +## **Preparation** + +
+ +### **Fluent Web Component v3 v.s Fluent React 9** + +
+ +**Component and Slot Mapping** + +| Fluent UI React 9 | Fluent Web Components 3 | +| ------------------- | ------------------------- | +| `` | `` | +| `` | `` | +| `` | `named slot = "heading"` | +| `` | `default slotted content` | + +
+ +**Property Mapping** +| Fluent UI React 9 | Fluent Web Components 3 | Description of difference | +|---------------------------|---------------------------|------------------------------------------------------------------------------------------| +| `defaultOpenItems: number`| `expand: boolean` | _FuiR9_ `defaultOpenItems` is a number property set on the `Accordion` corresponding to the intended `AccordionItem` to be expanded.
`expand` is a boolean property set directly on the `AccordionItem` intended to be expanded. +| `multiple: boolean` | `expandmode: "single"` | `"multiple"`| | +| `size` | `size` | +| `as: 'h1'` | `'h2'` | `'h3'` | `'h4'` | `'h5'` | `'h6'` | `headinglevel: 1` | `2` | `3` | `4` | `5` | `6` | `as` property sets a wrapper around the `AccordionItem` header with the corresponding header tag ( `h1`, `h2`, etc. )
`headinglevel` sets the `aria-level` attribute to the corresponding heading level. +| `disabled` | `disabled` | +| `expandIconPosition` | `expandIconPosition` | +| `expandIcon` | `named slot: collapsed-icon` + `expanded-icon` | `expandIcon` is a prop that is passed a ternary to render the appropriate icon.
`collapsed-icon` and `expanded-icon` are named slots to supply the appropriate icons. +| `icon` | `named slot: start` + `end` | `icon` is a property set on the `AccordionHeader` through which an icon is passed
`start` and `end` are named slots through which to supply a presentation icon. diff --git a/packages/web-components/src/accordion/accordion.definition.ts b/packages/web-components/src/accordion/accordion.definition.ts new file mode 100644 index 0000000000000..aa47c704ae1a8 --- /dev/null +++ b/packages/web-components/src/accordion/accordion.definition.ts @@ -0,0 +1,19 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Accordion } from './accordion.js'; +import { styles } from './accordion.styles.js'; +import { template } from './accordion.template.js'; + +/** + * The Fluent Accordion Element. Implements {@link @microsoft/fast-foundation#Accordion }, + * {@link @microsoft/fast-foundation#accordionTemplate} + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = Accordion.compose({ + name: `${FluentDesignSystem.prefix}-accordion`, + template, + styles, +}); diff --git a/packages/web-components/src/accordion/accordion.stories.ts b/packages/web-components/src/accordion/accordion.stories.ts new file mode 100644 index 0000000000000..38cdd5ceb2906 --- /dev/null +++ b/packages/web-components/src/accordion/accordion.stories.ts @@ -0,0 +1,208 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../helpers.stories.js'; +import { AccordionItemExpandIconPosition, AccordionItemSize } from '../accordion-item/accordion-item.options.js'; +import type { Accordion as FluentAccordion } from './accordion.js'; +import './define'; +import '../accordion-item/define'; + +type AccordionStoryArgs = Args & FluentAccordion; +type AccordionStoryMeta = Meta; + +const add20Filled = html` + +`; +const subtract20Filled = html` + +`; + +const eye20Regular = html` + +`; +const eyeOff20Regular = html` + +`; + +const storyTemplate = html` + x.expandMode}> + x.size} + heading-level=${x => x.headingLevel} + expand-icon-position=${x => x.expandIconPosition} + block=${x => x.block} + ?disabled=${x => x.disabled} + > + Accordion Header 1 + Accordion Panel 1 + + x.size} + heading-level=${x => x.headingLevel} + expand-icon-position=${x => x.expandIconPosition} + block=${x => x.block} + ?disabled=${x => x.disabled} + > + Accordion Header 1 + Accordion Panel 2 + + x.size} + heading-level=${x => x.headingLevel} + expand-icon-position=${x => x.expandIconPosition} + block=${x => x.block} + ?disabled=${x => x.disabled} + > + Accordion Header 1 + Accordion Panel 3 + + +`; + +export default { + title: 'Components/Accordion', + args: { + size: 'medium', + expandIconPosition: 'start', + expandMode: 'multiple', + block: false, + disabled: false, + headingLevel: '2', + }, + argTypes: { + size: { + description: 'Sets the size of the Accordion Item header', + table: { + defaultValue: { summary: 'medium' }, + }, + control: { + type: 'select', + options: Object.values(AccordionItemSize), + }, + defaultValue: 'medium', + }, + expandIconPosition: { + description: 'Sets position of expand and collapse icon', + table: { + defaultValue: { summary: 'start' }, + }, + control: { + type: 'select', + options: Object.values(AccordionItemExpandIconPosition), + }, + defaultValue: 'start', + }, + expandMode: { + description: 'Sets whether multiple or a single accordion item can be expanded at one time', + table: { + defaultValue: { summary: 'multiple' }, + }, + control: { + type: 'select', + options: ['multiple', 'single'], + }, + defaultValue: 'multiple', + }, + block: { + description: 'Sets focus state width', + table: { + defaultValue: { summary: false }, + }, + control: 'boolean', + defaultValue: false, + }, + disabled: { + description: 'Sets disabled state on Accordion Item', + table: { + defaultValue: { summary: false }, + }, + control: 'boolean', + defaultValue: false, + }, + headingLevel: { + description: 'Sets `aria-level` attribute on Accordion Item heading', + table: { + defaultValue: { summary: '2' }, + }, + control: { + type: 'select', + options: ['1', '2', '3', '4', '5', '6'], + }, + defaultValue: '2', + }, + }, +} as AccordionStoryMeta; + +export const Accordion = renderComponent(storyTemplate).bind({}); + +export const AccordionWithCustomIcons = renderComponent(html` + + + ${add20Filled} + ${subtract20Filled} + Accordion Header 1 + Accordion Panel 1 + + + ${add20Filled} + ${subtract20Filled} + Accordion Header 2 + Accordion Panel 1 + + + ${add20Filled} + ${subtract20Filled} + Accordion Header 3 + Accordion Panel 1 + + +`); + +export const AccordionWithPresentationIcons = renderComponent(html` + + + ${eye20Regular} + ${eyeOff20Regular} + Accordion Header 1 + Accordion Panel 1 + + + ${eye20Regular} + ${eyeOff20Regular} + Accordion Header 2 + Accordion Panel 1 + + + ${eye20Regular} + ${eyeOff20Regular} + Accordion Header 3 + Accordion Panel 1 + + +`); diff --git a/packages/web-components/src/accordion/accordion.styles.ts b/packages/web-components/src/accordion/accordion.styles.ts new file mode 100644 index 0000000000000..27ef26a8101e8 --- /dev/null +++ b/packages/web-components/src/accordion/accordion.styles.ts @@ -0,0 +1,11 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; + +export const styles = css` + ${display('flex')} + + :host { + flex-direction: column; + width: 100%; + } +`; diff --git a/packages/web-components/src/accordion/accordion.template.ts b/packages/web-components/src/accordion/accordion.template.ts new file mode 100644 index 0000000000000..f1a1d903ecd00 --- /dev/null +++ b/packages/web-components/src/accordion/accordion.template.ts @@ -0,0 +1,5 @@ +import { ElementViewTemplate } from '@microsoft/fast-element'; +import { accordionTemplate } from '@microsoft/fast-foundation'; +import type { Accordion } from './accordion.js'; + +export const template: ElementViewTemplate = accordionTemplate(); diff --git a/packages/web-components/src/accordion/accordion.ts b/packages/web-components/src/accordion/accordion.ts new file mode 100644 index 0000000000000..ba6f6432fbf67 --- /dev/null +++ b/packages/web-components/src/accordion/accordion.ts @@ -0,0 +1,7 @@ +import { FASTAccordion } from '@microsoft/fast-foundation'; + +/** + * The base class used for constructing a fluent-accordion custom element + * @public + */ +export class Accordion extends FASTAccordion {} diff --git a/packages/web-components/src/accordion/define.ts b/packages/web-components/src/accordion/define.ts new file mode 100644 index 0000000000000..b3b6469ee7c25 --- /dev/null +++ b/packages/web-components/src/accordion/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './accordion.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/accordion/index.ts b/packages/web-components/src/accordion/index.ts new file mode 100644 index 0000000000000..c6b994bfc7c02 --- /dev/null +++ b/packages/web-components/src/accordion/index.ts @@ -0,0 +1,4 @@ +export * from './accordion.js'; +export { template as accordionTemplate } from './accordion.template.js'; +export { styles as accordionStyles } from './accordion.styles.js'; +export { definition as accordionDefinition } from './accordion.definition.js'; diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index 78cf3190790a6..23376a3e515d8 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -1,3 +1,5 @@ +export * from './accordion/index.js'; +export * from './accordion-item/index.js'; export * from './badge/index.js'; export * from './counter-badge/index.js'; export * from './progress-bar/index.js'; From ffe28d340f31c2191ce75955183edf4e04782b35 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Wed, 22 Feb 2023 04:22:51 +0000 Subject: [PATCH 034/203] applying package updates --- ...ents-ee0dceff-c555-429c-b688-92aa40dc7f5e.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) delete mode 100644 change/@fluentui-web-components-ee0dceff-c555-429c-b688-92aa40dc7f5e.json diff --git a/change/@fluentui-web-components-ee0dceff-c555-429c-b688-92aa40dc7f5e.json b/change/@fluentui-web-components-ee0dceff-c555-429c-b688-92aa40dc7f5e.json deleted file mode 100644 index 90b77cef0e94f..0000000000000 --- a/change/@fluentui-web-components-ee0dceff-c555-429c-b688-92aa40dc7f5e.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat(accordion): Add accordion web component", - "packageName": "@fluentui/web-components", - "email": "brianbrady@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index c967ddfc98bf7..81b6b1986020b 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Wed, 22 Feb 2023 04:22:43 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.5", + "version": "3.0.0-alpha.5", + "comments": { + "prerelease": [ + { + "author": "brianbrady@microsoft.com", + "package": "@fluentui/web-components", + "commit": "1ad2597f744bf7c3e2eada7720eea793fcee660e", + "comment": "feat(accordion): Add accordion web component" + } + ] + } + }, { "date": "Tue, 21 Feb 2023 04:21:36 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.4", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index 656153860431b..2b4a1770e0872 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Thu, 16 Feb 2023 16:51:48 GMT and should not be manually modified. +This log was last generated on Wed, 22 Feb 2023 04:22:43 GMT and should not be manually modified. +## [3.0.0-alpha.5](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.5) + +Wed, 22 Feb 2023 04:22:43 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.4..@fluentui/web-components_v3.0.0-alpha.5) + +### Changes + +- feat(accordion): Add accordion web component ([PR #26547](https://github.com/microsoft/fluentui/pull/26547) by brianbrady@microsoft.com) + ## [3.0.0-alpha.4](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.4) Thu, 16 Feb 2023 16:51:48 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index bca9d2d85006c..251d7b778232f 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.4", + "version": "3.0.0-alpha.5", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 609aa4752fe1b3f4bcb48a478b843e02d6c1cc09 Mon Sep 17 00:00:00 2001 From: Miroslav Stastny Date: Wed, 22 Feb 2023 12:08:27 +0100 Subject: [PATCH 035/203] fix(ci): check changes folder exists (#26941) * fix(ci): skip changes files check if the changes folder does not exist * test for empty changes folder --- scripts/beachball/check-wc-3-changefiles.js | 5 +++++ scripts/beachball/check-wc-3-changefiles.spec.ts | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/scripts/beachball/check-wc-3-changefiles.js b/scripts/beachball/check-wc-3-changefiles.js index 8ed3ca8301bfb..b317c41cec5f8 100644 --- a/scripts/beachball/check-wc-3-changefiles.js +++ b/scripts/beachball/check-wc-3-changefiles.js @@ -27,6 +27,11 @@ if (isExecutedFromCli) { * - Usage needs to be removed from .github/workflows/check-packages.yml */ function main(/** @type {string} */ root) { + if (!fs.existsSync(root)) { + console.log('✅ Changes folder does not exist, skipping check.'); + return; + } + const changeFiles = fs.readdirSync(root, 'utf8'); const invalidChangeFiles = /** @type string [] */ (changeFiles diff --git a/scripts/beachball/check-wc-3-changefiles.spec.ts b/scripts/beachball/check-wc-3-changefiles.spec.ts index f53b761cff3d5..f9e4979040926 100644 --- a/scripts/beachball/check-wc-3-changefiles.spec.ts +++ b/scripts/beachball/check-wc-3-changefiles.spec.ts @@ -49,6 +49,22 @@ describe(`Name of the group`, () => { expect(consoleErrorSpy).not.toHaveBeenCalled(); }); + it(`should pass if changes folder does not exist`, () => { + const { root, consoleErrorSpy, processExitSpy } = setup([]); + main(path.join(root, 'invalid')); + + expect(processExitSpy).not.toHaveBeenCalled(); + expect(consoleErrorSpy).not.toHaveBeenCalled(); + }); + + it(`should pass if changes folder is empty`, () => { + const { root, consoleErrorSpy, processExitSpy } = setup([]); + main(root); + + expect(processExitSpy).not.toHaveBeenCalled(); + expect(consoleErrorSpy).not.toHaveBeenCalled(); + }); + it(`should fail if there is invalid changefile`, () => { const changeFiles: Array = [ { From 2f18c500b339692101e7ec4494b7a98f0eaf0300 Mon Sep 17 00:00:00 2001 From: Miroslav Stastny Date: Wed, 22 Feb 2023 13:06:23 +0100 Subject: [PATCH 036/203] fix(ci): overwrite existing data when publishing WC storybook (#26939) --- .github/workflows/azure-storage-web-components.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/azure-storage-web-components.yml b/.github/workflows/azure-storage-web-components.yml index 622342226db38..68f863e032b0e 100644 --- a/.github/workflows/azure-storage-web-components.yml +++ b/.github/workflows/azure-storage-web-components.yml @@ -36,4 +36,4 @@ jobs: uses: Azure/cli@v1.0.7 with: # Specify the script here - inlineScript: az storage blob upload-batch --account-name webcomponentsdocsite --auth-mode key -d '$web' -s ./packages/web-components/dist/storybook + inlineScript: az storage blob upload-batch --overwrite --account-name webcomponentsdocsite --auth-mode key -d '$web' -s ./packages/web-components/dist/storybook From db9bcd853bc57691f327df3a565c432f8adf0d16 Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Thu, 23 Feb 2023 16:28:56 -0800 Subject: [PATCH 037/203] Web Component Switch (#26517) * switch init * provides export path * yarn change * removes dead code * adds table docs * updates attribute to use attr syntax * removes on/off text for label only * addresses PR feedback * updates label font-weight * removes dead code * updates styles * adds required styles for switch * Update change/@fluentui-web-components-a74d6518-0d94-4e22-bd9f-70ea63a066ab.json Co-authored-by: Miroslav Stastny * removes unuses import * api report * removes dead code * updates styles and story * optimizes styles * reverts api report * removes unchecked checked message styles * updates labelPosition type to include undefined * updates helper import * optimizes css * cleans up styles * optimizes styles * uses design tokens * removes dead import * removes dead code * removes required styling from label * adds switch readme * fixes docs * fixes switch hover styles * formats switch styles * alphabetizes exports --------- Co-authored-by: Miroslav Stastny --- ...-a74d6518-0d94-4e22-bd9f-70ea63a066ab.json | 7 + packages/web-components/package.json | 4 + packages/web-components/src/index.ts | 1 + packages/web-components/src/switch/README.md | 121 +++++++++++++++ packages/web-components/src/switch/define.ts | 4 + packages/web-components/src/switch/index.ts | 5 + .../src/switch/switch.definition.ts | 17 +++ .../src/switch/switch.options.ts | 17 +++ .../src/switch/switch.stories.ts | 88 +++++++++++ .../src/switch/switch.styles.ts | 144 ++++++++++++++++++ .../src/switch/switch.template.ts | 7 + packages/web-components/src/switch/switch.ts | 16 ++ 12 files changed, 431 insertions(+) create mode 100644 change/@fluentui-web-components-a74d6518-0d94-4e22-bd9f-70ea63a066ab.json create mode 100644 packages/web-components/src/switch/README.md create mode 100644 packages/web-components/src/switch/define.ts create mode 100644 packages/web-components/src/switch/index.ts create mode 100644 packages/web-components/src/switch/switch.definition.ts create mode 100644 packages/web-components/src/switch/switch.options.ts create mode 100644 packages/web-components/src/switch/switch.stories.ts create mode 100644 packages/web-components/src/switch/switch.styles.ts create mode 100644 packages/web-components/src/switch/switch.template.ts create mode 100644 packages/web-components/src/switch/switch.ts diff --git a/change/@fluentui-web-components-a74d6518-0d94-4e22-bd9f-70ea63a066ab.json b/change/@fluentui-web-components-a74d6518-0d94-4e22-bd9f-70ea63a066ab.json new file mode 100644 index 0000000000000..d7ef06b823afd --- /dev/null +++ b/change/@fluentui-web-components-a74d6518-0d94-4e22-bd9f-70ea63a066ab.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat(switch): Add switch web component", + "packageName": "@fluentui/web-components", + "email": "brianbrady@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 251d7b778232f..b2d4606b5c255 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -48,6 +48,10 @@ "types": "./dist/esm/progress-bar/define.d.ts", "default": "./dist/esm/progress-bar/define.js" }, + "./switch": { + "types": "./dist/esm/switch/define.d.ts", + "default": "./dist/esm/switch/define.js" + }, "./spinner": { "types": "./dist/esm/spinner/define.d.ts", "default": "./dist/esm/spinner/define.js" diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index 23376a3e515d8..f259843fc5e6f 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -4,6 +4,7 @@ export * from './badge/index.js'; export * from './counter-badge/index.js'; export * from './progress-bar/index.js'; export * from './spinner/index.js'; +export * from './switch/index.js'; export * from './text/index.js'; export * from './theme/index.js'; diff --git a/packages/web-components/src/switch/README.md b/packages/web-components/src/switch/README.md new file mode 100644 index 0000000000000..37c41df443537 --- /dev/null +++ b/packages/web-components/src/switch/README.md @@ -0,0 +1,121 @@ +# Switch + +> An implementation of a [switch](https://w3c.github.io/aria/#switch) as a form-connected web-component. + +
+ +## **Design Spec** + +[Link to Switch Design Spec in Figma](https://www.figma.com/file/TPQVDN5cxYBqkP9urETsCp/Switch?node-id=655%3A1158&t=kJMaMie08ejCnL7H-0) + +
+ +## **Engineering Spec** + +Fluent WC3 Switch extends from the [FAST Switch](https://www.fast.design/docs/components/switch/) and is intended to be as close to the Fluent UI React 9 Switch implementation as possible. However, due to the nature of web components there will not be 100% parity between the two. + +### Use Case + +Typical use cases include, but are not limited to, turning a feature on and off or showing or hiding a piece of UI + +
+ +## Class: `Switch` + +
+ +### **Component Name** + +`fluent-switch` + +
+ +### **Variables** + +
+ +### **Fields** + +| Name | Privacy | Type | Default | Description | +| --------------- | ------- | ------------------------------ | ---------- | ------------------------------------------------------ | +| `checked` | public | `boolean` | | Specifies whether switch input is checked | +| `required` | public | `boolean` | `false` | Specifies required styling for switch | +| `disabled` | public | `boolean` | `false` | Sets disabled state for switch | +| `labelPosition` | public | `"small"` `"medium"` `"large"` | `"medium"` | Specifies position of the label relative to the switch | + +
+ +### **Methods** + +
+ +### **Events** + +| Name | Type | Description | Inherited From | +| ------ | ---- | ----------- | ---------------------------------------------------------- | --- | +| change | | | Emits a custom change event when the checked state changes | | + +
+ +### **Attributes** + +| Name | Field | +| ---------------- | ------------- | +| `required` | required | +| `disabled` | disabled | +| `checked` | checked | +| `label-position` | labelPosition | + +
+ +### **Slots** + +| Name | Description | +| ---- | ------------------------------------- | +| | Default slotted content for the label | + +
+
+
+ +### **Template** + +`switchTemplate` from FastFoundation + +
+ +## **Accessibility** + +[W3 Switch Spec](https://w3c.github.io/aria/#switch) + +
+ +### **WAI-ARIA Roles, States, and Properties** + +- `aria-checked` +- `aria-disabled` + +
+
+
+ +## **Preparation** + +
+ +### **Fluent Web Component v3 v.s Fluent React 9** + +
+ +**Component and Slot Mapping** + +| Fluent UI React 9 | Fluent Web Components 3 | +| ----------------- | ----------------------- | +| `` | `` | + +
+ +**Property Mapping** +| Fluent UI React 9 | Fluent Web Components 3 | Description of difference | +|--------------------- |------------------------ |---------------------------| +| `` | default slotted content | React implementation requires user to pass label through `prop` on the Switch
The web components implementation requires user to pass the label through the default slotted content diff --git a/packages/web-components/src/switch/define.ts b/packages/web-components/src/switch/define.ts new file mode 100644 index 0000000000000..de034c8ea7409 --- /dev/null +++ b/packages/web-components/src/switch/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './switch.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/switch/index.ts b/packages/web-components/src/switch/index.ts new file mode 100644 index 0000000000000..f914ee58963af --- /dev/null +++ b/packages/web-components/src/switch/index.ts @@ -0,0 +1,5 @@ +export * from './switch.js'; +export * from './switch.options.js'; +export { definition } from './switch.definition.js'; +export { styles as switchStyles } from './switch.styles.js'; +export { template as switchTemplate } from './switch.template.js'; diff --git a/packages/web-components/src/switch/switch.definition.ts b/packages/web-components/src/switch/switch.definition.ts new file mode 100644 index 0000000000000..68e19febf5a6e --- /dev/null +++ b/packages/web-components/src/switch/switch.definition.ts @@ -0,0 +1,17 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Switch } from './switch.js'; +import { template } from './switch.template.js'; +import { styles } from './switch.styles.js'; + +/** + * The Fluent Switch Element. + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = Switch.compose({ + name: `${FluentDesignSystem.prefix}-switch`, + template, + styles, +}); diff --git a/packages/web-components/src/switch/switch.options.ts b/packages/web-components/src/switch/switch.options.ts new file mode 100644 index 0000000000000..4f2441ce61690 --- /dev/null +++ b/packages/web-components/src/switch/switch.options.ts @@ -0,0 +1,17 @@ +import { ValuesOf } from '@microsoft/fast-foundation'; + +/** + * SwitchLabelPosition Constants + * @public + */ +export const SwitchLabelPosition = { + above: 'above', + after: 'after', + before: 'before', +} as const; + +/** + * Applies label position + * @public + */ +export type SwitchLabelPosition = ValuesOf; diff --git a/packages/web-components/src/switch/switch.stories.ts b/packages/web-components/src/switch/switch.stories.ts new file mode 100644 index 0000000000000..13ece9c67f1c0 --- /dev/null +++ b/packages/web-components/src/switch/switch.stories.ts @@ -0,0 +1,88 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../helpers.stories.js'; +import type { Switch as FluentSwitch } from './switch.js'; +import './define.js'; +import { SwitchLabelPosition } from './switch.options.js'; + +type SwitchStoryArgs = Args & FluentSwitch; +type SwitchStoryMeta = Meta; + +const storyTemplate = html` +
+ x.checked} + ?disabled=${x => x.disabled} + ?required=${x => x.required} + label-position=${x => x.labelPosition} + value="${x => x.value}" + > + ${x => x.value} + +
+`; + +export default { + title: 'Components/Switch', + args: { + checked: false, + disabled: false, + required: false, + labelPosition: 'after', + }, + argTypes: { + labelPosition: { + options: Object.values(SwitchLabelPosition), + control: { + type: 'select', + }, + table: { + type: { + summary: 'Sets the position of label', + }, + defaultValue: { + summary: 'after', + }, + }, + }, + checked: { + control: 'boolean', + table: { + type: { + summary: 'Sets checked state', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + disabled: { + control: 'boolean', + table: { + type: { + summary: 'Sets disabled state', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + required: { + control: 'boolean', + table: { + type: { + summary: 'Sets required state', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + value: { + control: 'text', + defaultValue: 'This is a label', + }, + }, +} as SwitchStoryMeta; + +export const Switch = renderComponent(storyTemplate).bind({}); diff --git a/packages/web-components/src/switch/switch.styles.ts b/packages/web-components/src/switch/switch.styles.ts new file mode 100644 index 0000000000000..d9ba3cf838bb1 --- /dev/null +++ b/packages/web-components/src/switch/switch.styles.ts @@ -0,0 +1,144 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + borderRadiusCircular, + colorCompoundBrandBackground, + colorCompoundBrandBackgroundHover, + colorCompoundBrandBackgroundPressed, + colorNeutralBackgroundDisabled, + colorNeutralForeground1, + colorNeutralForeground3, + colorNeutralForeground3Hover, + colorNeutralForeground3Pressed, + colorNeutralForegroundDisabled, + colorNeutralForegroundInverted, + colorNeutralForegroundInvertedHover, + colorNeutralForegroundInvertedPressed, + colorNeutralStrokeAccessible, + colorNeutralStrokeAccessibleHover, + colorNeutralStrokeAccessiblePressed, + colorNeutralStrokeDisabled, + colorTransparentBackground, + curveEasyEase, + durationNormal, + fontFamilyBase, + fontSizeBase300, + fontWeightRegular, + lineHeightBase300, + spacingHorizontalS, + spacingHorizontalXS, + spacingHorizontalXXS, + spacingVerticalS, + spacingVerticalXS, +} from '../theme/design-tokens.js'; + +export const styles = css` + ${display('inline-flex')} + + :host { + align-items: center; + flex-direction: row-reverse; + outline: none; + user-select: none; + } + :host([label-position='before']) { + flex-direction: row; + } + :host([label-position='above']) { + flex-direction: column; + align-items: flex-start; + } + :host([disabled]) .label, + :host([readonly]) .label, + :host([readonly]) .switch, + :host([disabled]) .switch { + cursor: not-allowed; + } + .label { + position: relative; + color: ${colorNeutralForeground1}; + line-height: ${lineHeightBase300}; + font-size: ${fontSizeBase300}; + font-weight: ${fontWeightRegular}; + font-family: ${fontFamilyBase}; + padding: ${spacingVerticalXS} ${spacingHorizontalXS}; + cursor: pointer; + } + .label__hidden { + display: none; + } + .switch { + display: flex; + align-items: center; + padding: 0 ${spacingHorizontalXXS}; + box-sizing: border-box; + width: 40px; + height: 20px; + background-color: ${colorTransparentBackground}; + border: 1px solid ${colorNeutralStrokeAccessible}; + border-radius: ${borderRadiusCircular}; + outline: none; + cursor: pointer; + margin: ${spacingVerticalS} ${spacingHorizontalS}; + } + :host(:hover) .switch { + background: none; + border-color: ${colorNeutralStrokeAccessibleHover}; + } + :host(:active) .switch { + border-color: ${colorNeutralStrokeAccessiblePressed}; + } + :host([disabled]) .switch, + :host([readonly]) .switch { + border: 1px solid ${colorNeutralStrokeDisabled}; + background-color: none; + pointer: default; + } + :host([aria-checked='true']) .switch { + background: ${colorCompoundBrandBackground}; + } + :host([aria-checked='true']:hover) .switch { + background: ${colorCompoundBrandBackgroundHover}; + border-color: ${colorCompoundBrandBackgroundHover}; + } + :host([aria-checked='true']:active) .switch { + background: ${colorCompoundBrandBackgroundPressed}; + border-color: ${colorCompoundBrandBackgroundPressed}; + } + :host([aria-checked='true'][disabled]) .switch { + background: ${colorNeutralBackgroundDisabled}; + border-color: ${colorNeutralStrokeDisabled}; + } + .checked-indicator { + height: 14px; + width: 14px; + border-radius: 50%; + background-color: ${colorNeutralForeground3}; + transition-duration: ${durationNormal}; + transition-timing-function: ${curveEasyEase}; + transition-property: transform; + } + :host([aria-checked='true']) .checked-indicator { + background-color: ${colorNeutralForegroundInverted}; + transform: translateX(20px); + } + :host([aria-checked='true']:hover) .checked-indicator { + background: ${colorNeutralForegroundInvertedHover}; + } + :host([aria-checked='true']:active) .checked-indicator { + background: ${colorNeutralForegroundInvertedPressed}; + } + :host(:hover) .checked-indicator { + background-color: ${colorNeutralForeground3Hover}; + } + :host(:active) .checked-indicator { + background-color: ${colorNeutralForeground3Pressed}; + } + :host([disabled]) .checked-indicator, + :host([readonly]) .checked-indicator { + background: ${colorNeutralForegroundDisabled}; + } + :host([aria-checked='true'][disabled]) .checked-indicator { + background: ${colorNeutralForegroundDisabled}; + } +`; diff --git a/packages/web-components/src/switch/switch.template.ts b/packages/web-components/src/switch/switch.template.ts new file mode 100644 index 0000000000000..c405389f9ad94 --- /dev/null +++ b/packages/web-components/src/switch/switch.template.ts @@ -0,0 +1,7 @@ +import { ElementViewTemplate } from '@microsoft/fast-element'; +import { switchTemplate } from '@microsoft/fast-foundation'; +import { Switch } from './switch.js'; + +export const template: ElementViewTemplate = switchTemplate({ + switch: ``, +}); diff --git a/packages/web-components/src/switch/switch.ts b/packages/web-components/src/switch/switch.ts new file mode 100644 index 0000000000000..7c96853ecc17b --- /dev/null +++ b/packages/web-components/src/switch/switch.ts @@ -0,0 +1,16 @@ +import { attr } from '@microsoft/fast-element'; +import { FASTSwitch } from '@microsoft/fast-foundation'; +import { SwitchLabelPosition } from './switch.options.js'; + +export class Switch extends FASTSwitch { + /** + * The label position of the switch + * + * @public + * @default 'after' + * @remarks + * HTML Attribute: labelposition + */ + @attr({ attribute: 'label-position' }) + public labelPosition: SwitchLabelPosition | undefined; +} From 05d14a6803863ad9ea6dbf3798f14684d8fedead Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Fri, 24 Feb 2023 04:20:39 +0000 Subject: [PATCH 038/203] applying package updates --- ...ents-a74d6518-0d94-4e22-bd9f-70ea63a066ab.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) delete mode 100644 change/@fluentui-web-components-a74d6518-0d94-4e22-bd9f-70ea63a066ab.json diff --git a/change/@fluentui-web-components-a74d6518-0d94-4e22-bd9f-70ea63a066ab.json b/change/@fluentui-web-components-a74d6518-0d94-4e22-bd9f-70ea63a066ab.json deleted file mode 100644 index d7ef06b823afd..0000000000000 --- a/change/@fluentui-web-components-a74d6518-0d94-4e22-bd9f-70ea63a066ab.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat(switch): Add switch web component", - "packageName": "@fluentui/web-components", - "email": "brianbrady@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 81b6b1986020b..fed39f77b5577 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Fri, 24 Feb 2023 04:20:32 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.6", + "version": "3.0.0-alpha.6", + "comments": { + "prerelease": [ + { + "author": "brianbrady@microsoft.com", + "package": "@fluentui/web-components", + "commit": "2de60aec984eb2802da76c6c67849da358c0db49", + "comment": "feat(switch): Add switch web component" + } + ] + } + }, { "date": "Wed, 22 Feb 2023 04:22:43 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.5", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index 2b4a1770e0872..0866f5a0ac53f 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Wed, 22 Feb 2023 04:22:43 GMT and should not be manually modified. +This log was last generated on Fri, 24 Feb 2023 04:20:32 GMT and should not be manually modified. +## [3.0.0-alpha.6](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.6) + +Fri, 24 Feb 2023 04:20:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.5..@fluentui/web-components_v3.0.0-alpha.6) + +### Changes + +- feat(switch): Add switch web component ([PR #26517](https://github.com/microsoft/fluentui/pull/26517) by brianbrady@microsoft.com) + ## [3.0.0-alpha.5](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.5) Wed, 22 Feb 2023 04:22:43 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index b2d4606b5c255..5c9856fd72548 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.5", + "version": "3.0.0-alpha.6", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 81e272b706db53c91c82a03f4c36b5b66bdc1bc5 Mon Sep 17 00:00:00 2001 From: Tudor Popa <97875118+tudorpopams@users.noreply.github.com> Date: Fri, 24 Feb 2023 16:46:50 +0100 Subject: [PATCH 039/203] fix(ci): update web components swa workflow (#26960) * fix(ci): update web components swa workflow update workflow add yarn as engine in package.json add engines section in web-components package.json remove engines section from web components package json fix output location remove run condition replace branch add manual trigger * remove workflow_dispatch directive * remove azure storage workflow for web components docsite --- .../azure-static-web-apps-deploy.yml | 4 +- .../azure-storage-web-components.yml | 39 ------------------- 2 files changed, 1 insertion(+), 42 deletions(-) delete mode 100644 .github/workflows/azure-storage-web-components.yml diff --git a/.github/workflows/azure-static-web-apps-deploy.yml b/.github/workflows/azure-static-web-apps-deploy.yml index 0d1a36770d84f..f539bbedac364 100644 --- a/.github/workflows/azure-static-web-apps-deploy.yml +++ b/.github/workflows/azure-static-web-apps-deploy.yml @@ -12,7 +12,6 @@ permissions: jobs: build_and_deploy: - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') runs-on: ubuntu-latest name: Build and Deploy Job steps: @@ -26,6 +25,5 @@ jobs: repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for GitHub integrations (i.e. PR comments) action: 'upload' app_build_command: 'yarn workspace @fluentui/web-components build-storybook' - app_location: '/packages/web-components' # App source code path relative to repository root - output_location: 'dist/storybook' # Built app content directory, relative to app_location - optional + output_location: 'packages/web-components/dist/storybook' # Built app content directory, relative to app_location - optional skip_api_build: true diff --git a/.github/workflows/azure-storage-web-components.yml b/.github/workflows/azure-storage-web-components.yml deleted file mode 100644 index 68f863e032b0e..0000000000000 --- a/.github/workflows/azure-storage-web-components.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Azure storage publish web components - -on: - # NOTE: manual workflows work only if workflow exists in default branch - which is not our case 👀 - # workflow_dispatch: - push: - branches: - - web-components-v3 - -permissions: - contents: read - pull-requests: write - -jobs: - build_and_deploy_job: - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') - runs-on: ubuntu-latest - name: Build and Deploy Job - steps: - - uses: actions/checkout@v2 - - - name: Setup Node.js environment - uses: actions/setup-node@v3.6.0 - with: - node-version: 14.x - - - run: yarn - - - run: yarn workspace @fluentui/web-components build-storybook - - - uses: azure/login@v1 - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - - - name: Azure CLI Action - uses: Azure/cli@v1.0.7 - with: - # Specify the script here - inlineScript: az storage blob upload-batch --overwrite --account-name webcomponentsdocsite --auth-mode key -d '$web' -s ./packages/web-components/dist/storybook From e85bac7b1c9331c52df6240d5553222af15b4c5a Mon Sep 17 00:00:00 2001 From: Hale Rankin Date: Fri, 24 Feb 2023 11:11:43 -0800 Subject: [PATCH 040/203] Adds Image web component (#26936) * Adds Image web component. * Removes unused portions of the doc file (now spec.md). Renames and simplifies the bordered attribute. Removes multiple image from first story. Adjusts style attribute selctor for bordered. * Removes unused CSS. Changes dimension of image used in first story. * Removes borderRadius attribute and related story code and styles. Adds CSS Guidance to spec to convey details about margin and border-radius values. Cleaned up story code. * Records results of yarn change * Updates package with reference to the component. Makes fit and shape optional. Replaces hard coded border radius value with token. * Update change/@fluentui-web-components-a862230b-9028-4c6a-8a43-3be819a6128e.json Co-authored-by: Miroslav Stastny --------- Co-authored-by: Chris Holt Co-authored-by: Miroslav Stastny --- ...-a862230b-9028-4c6a-8a43-3be819a6128e.json | 7 + packages/web-components/package.json | 4 + packages/web-components/src/image/define.ts | 4 + .../src/image/image.definition.ts | 17 ++ .../web-components/src/image/image.options.ts | 30 +++ .../web-components/src/image/image.spec.md | 62 +++++ .../web-components/src/image/image.stories.ts | 230 ++++++++++++++++++ .../web-components/src/image/image.styles.ts | 52 ++++ .../src/image/image.template.ts | 8 + packages/web-components/src/image/image.ts | 54 ++++ packages/web-components/src/image/index.ts | 5 + packages/web-components/src/index.ts | 1 + 12 files changed, 474 insertions(+) create mode 100644 change/@fluentui-web-components-a862230b-9028-4c6a-8a43-3be819a6128e.json create mode 100644 packages/web-components/src/image/define.ts create mode 100644 packages/web-components/src/image/image.definition.ts create mode 100644 packages/web-components/src/image/image.options.ts create mode 100644 packages/web-components/src/image/image.spec.md create mode 100644 packages/web-components/src/image/image.stories.ts create mode 100644 packages/web-components/src/image/image.styles.ts create mode 100644 packages/web-components/src/image/image.template.ts create mode 100644 packages/web-components/src/image/image.ts create mode 100644 packages/web-components/src/image/index.ts diff --git a/change/@fluentui-web-components-a862230b-9028-4c6a-8a43-3be819a6128e.json b/change/@fluentui-web-components-a862230b-9028-4c6a-8a43-3be819a6128e.json new file mode 100644 index 0000000000000..5dc002fd61244 --- /dev/null +++ b/change/@fluentui-web-components-a862230b-9028-4c6a-8a43-3be819a6128e.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat(image): Add image web component", + "packageName": "@fluentui/web-components", + "email": "harankin@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 5c9856fd72548..2652825beb712 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -40,6 +40,10 @@ "types": "./dist/esm/counter-badge/define.d.ts", "default": "./dist/esm/counter-badge/define.js" }, + "./image": { + "types": "./dist/esm/image/define.d.ts", + "default": "./dist/esm/image/define.js" + }, "./text": { "types": "./dist/esm/text/define.d.ts", "default": "./dist/esm/text/define.js" diff --git a/packages/web-components/src/image/define.ts b/packages/web-components/src/image/define.ts new file mode 100644 index 0000000000000..002c77e34e522 --- /dev/null +++ b/packages/web-components/src/image/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './image.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/image/image.definition.ts b/packages/web-components/src/image/image.definition.ts new file mode 100644 index 0000000000000..4e452fcc3a13e --- /dev/null +++ b/packages/web-components/src/image/image.definition.ts @@ -0,0 +1,17 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Image } from './image.js'; +import { template } from './image.template.js'; +import { styles } from './image.styles.js'; + +/** + * The Fluent Image Element + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = Image.compose({ + name: `${FluentDesignSystem.prefix}-image`, + template, + styles, +}); diff --git a/packages/web-components/src/image/image.options.ts b/packages/web-components/src/image/image.options.ts new file mode 100644 index 0000000000000..fe68ac66892e1 --- /dev/null +++ b/packages/web-components/src/image/image.options.ts @@ -0,0 +1,30 @@ +import { ValuesOf } from '@microsoft/fast-foundation'; + +/** + * Image fit + * @public + */ +export const ImageFit = { + none: 'none', + center: 'center', + contain: 'contain', + cover: 'cover', + default: 'default', +} as const; +/** + * Types for image fit + * @public + */ +export type ImageFit = ValuesOf; + +/** + * Image shape + * @public + */ +export const ImageShape = { + circular: 'circular', + rounded: 'rounded', + square: 'square', +} as const; + +export type ImageShape = ValuesOf; diff --git a/packages/web-components/src/image/image.spec.md b/packages/web-components/src/image/image.spec.md new file mode 100644 index 0000000000000..d2dba58db8142 --- /dev/null +++ b/packages/web-components/src/image/image.spec.md @@ -0,0 +1,62 @@ +# Fluent Image Component + +## Component Description + +Images, like photos and illustrations, help reinforce a message and express your product or app’s style. + +## Design Spec + +[Image Spec in Figma](https://www.figma.com/file/05wt6TAsEmgsCVZfPrpcWx/Image?t=uEvu1KnTefdTZHJC-6) + +## Engineering Spec + +### Inputs + +**content** + +- @attr public alt: string | Requires description if image role is not set to presentation. +- @attr public role: string +- @attr public src: string + +**booleans** + +- @attr public block: boolean | false +- @attr public border: boolean | false +- @attr public shadow: boolean | false + +**options** + +- @attr public fit: 'none' | 'center' | 'contain' | 'cover' | 'default' +- @attr public shape: 'square' | 'rounded' | 'circular' + +### Slots + +1 slot for developer to add element. + +## Accessibility + +The image element requires an alt tag when not used in role: presentation. + +## Preparation + +This will extend the FASTElement. + +Open GitHub issues related to Image component + +- [Feature request](https://github.com/microsoft/fluentui/issues/26452) +- [Bug](https://github.com/microsoft/fluentui/issues/26399) + +## Implementation + +### CSS Guidance + +- [x] Uses design tokens for styling + +An optional border-radius can be expressed using the following design tokens: + +- borderRadiusSmall, +- borderRadiusMedium, +- borderRadiusLarge +- borderRadiusXLarge + +An optional 16px margin can be added to the image to separate it from surrounding content. diff --git a/packages/web-components/src/image/image.stories.ts b/packages/web-components/src/image/image.stories.ts new file mode 100644 index 0000000000000..b5ed33ed14daa --- /dev/null +++ b/packages/web-components/src/image/image.stories.ts @@ -0,0 +1,230 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../helpers.stories.js'; +import type { Image as FluentImage } from './image.js'; +import { ImageFit, ImageShape } from './image.options.js'; +import './define.js'; + +type ImageStoryArgs = Args & FluentImage; +type ImageStoryMeta = Meta; + +const imageTemplate = html` +
+ x.block} + ?bordered=${x => x.bordered} + fit=${x => x.fit} + ?shadow=${x => x.shadow} + shape=${x => x.shape} + > + Short image description + +
+`; + +export default { + title: 'Components/Image', + args: { + block: false, + bordered: false, + shadow: false, + fit: ImageFit.default, + shape: ImageShape.square, + }, + argTypes: { + alt: { + description: 'Alternate text description -- to be supplied by component consumer', + table: { + type: { + summary: + 'Required. Alt tag provides text attribution for images. Should be brief but accurate—one or two sentences that describe the image and its context. If the image represents a function, be sure to indicate that. If it’s meant to be consumed with other objects on the page, consider that as well. Don’t repeat information that’s on the page in alt text since screen readers will read it twice.', + }, + }, + }, + block: { + description: + 'An image can use the argument ‘block’ so that it’s width will expand to fiill the available container space.', + table: { + defaultValue: { + summary: false, + }, + }, + }, + bordered: { + description: 'Border surrounding image', + table: { + type: { + summary: 'Use this option to provide minimal visual separation between image and surrounding content.', + }, + defaultValue: { + summary: false, + }, + }, + }, + fit: { + description: 'Determines how the image will be scaled and positioned within its parent container.', + table: { + defaultValue: { + summary: 'default', + }, + }, + options: Object.values(ImageFit), + control: 'select', + }, + role: { + description: 'Aria role -- to be supplied by component consumer', + table: { + type: { + summary: + 'If images are solely decorative and don’t provide useful information or context, use role=”presentation” to hide them from assistive technologies.', + }, + }, + }, + shadow: { + description: 'Apply an optional box shadow to further separate the image from the background.', + table: { + type: { + summary: + 'To give an image additional prominence, use the shadow prop to make it appear elevated. Too many shadows can cause a busy layout, so use them sparingly.', + }, + defaultValue: { + summary: false, + }, + }, + }, + shape: { + description: 'Image shape', + table: { + defaultValue: { + summary: 'square', + }, + }, + options: Object.values(ImageShape), + control: 'select', + }, + src: { + description: 'Image source -- to be supplied by component consumer', + table: { + type: { + summary: 'Required', + }, + }, + }, + }, +} as ImageStoryMeta; + +export const Image = renderComponent(imageTemplate).bind({}); + +// Block layout +const imageLayoutBlock = html` +
+ + + + +
+`; +export const BlockLayout = renderComponent(imageLayoutBlock).bind({}); + +// Fit: None +const imageFitNoneLarge = html` +
+ + + +
+`; +export const ImageFitNoneLarge = renderComponent(imageFitNoneLarge).bind({}); + +const imageFitNoneSmall = html` +
+ + 200x100 placeholder + +
+`; +export const ImageFitNoneSmall = renderComponent(imageFitNoneSmall).bind({}); + +// Fit: Center +const imageFitCenterLarge = html` +
+ + + +
+`; +export const ImageFitCenterLarge = renderComponent(imageFitCenterLarge).bind({}); + +const imageFitCenterSmall = html` +
+ + image layout story + +
+`; +export const ImageFitCenterSmall = renderComponent(imageFitCenterSmall).bind({}); + +const imageFitContain = html` +
+ + image layout story + +
+`; +export const ImageFitContain = renderComponent(imageFitContain).bind({}); + +const imageFitContainTall = html` +
+ + image layout story + +
+`; +export const ImageFitContainTall = renderComponent(imageFitContainTall).bind({}); + +const imageFitContainWide = html` +
+ + image layout story + +
+`; +export const ImageFitContainWide = renderComponent(imageFitContainWide).bind({}); + +// Fit: Cover +const imageFitCoverSmall = html` +
+ + image layout story + +
+`; +export const ImageFitCoverSmall = renderComponent(imageFitCoverSmall).bind({}); + +const imageFitCoverMedium = html` +
+ + image layout story + +
+`; +export const ImageFitCoverMedium = renderComponent(imageFitCoverMedium).bind({}); + +const imageFitCoverLarge = html` +
+ + image layout story + +
+`; +export const ImageFitCoverLarge = renderComponent(imageFitCoverLarge).bind({}); + +// Fit: Default +const imageFitDefault = html` +
+ + image layout story + +
+`; +export const ImageFitDefault = renderComponent(imageFitDefault).bind({}); diff --git a/packages/web-components/src/image/image.styles.ts b/packages/web-components/src/image/image.styles.ts new file mode 100644 index 0000000000000..34c04cf72590e --- /dev/null +++ b/packages/web-components/src/image/image.styles.ts @@ -0,0 +1,52 @@ +import { css } from '@microsoft/fast-element'; +import { borderRadiusCircular, colorNeutralStroke2, shadow4, strokeWidthThin } from '../theme/design-tokens.js'; + +/** Image styles + * + * @public + */ +export const styles = css` + :host ::slotted(img) { + box-sizing: border-box; + min-height: 8px; + min-width: 8px; + display: inline-block; + } + :host([block]) ::slotted(img) { + width: 100%; + height: auto; + } + :host([bordered]) ::slotted(img) { + border: ${strokeWidthThin} solid ${colorNeutralStroke2}; + } + :host([fit='none']) ::slotted(img) { + object-fit: none; + object-position: top left; + height: 100%; + width: 100%; + } + :host([fit='center']) ::slotted(img) { + object-fit: none; + object-position: center; + height: 100%; + width: 100%; + } + :host([fit='contain']) ::slotted(img) { + object-fit: contain; + object-position: center; + height: 100%; + width: 100%; + } + :host([fit='cover']) ::slotted(img) { + object-fit: cover; + object-position: center; + height: 100%; + width: 100%; + } + :host([shadow]) ::slotted(img) { + box-shadow: ${shadow4}; + } + :host([shape='circular']) ::slotted(img) { + border-radius: ${borderRadiusCircular}; + } +`; diff --git a/packages/web-components/src/image/image.template.ts b/packages/web-components/src/image/image.template.ts new file mode 100644 index 0000000000000..9307a3c7d72ea --- /dev/null +++ b/packages/web-components/src/image/image.template.ts @@ -0,0 +1,8 @@ +import { ElementViewTemplate, html } from '@microsoft/fast-element'; +import type { Image } from './image.js'; + +/** + * Template for the Image component + * @public + */ +export const template: ElementViewTemplate = html``; diff --git a/packages/web-components/src/image/image.ts b/packages/web-components/src/image/image.ts new file mode 100644 index 0000000000000..c93f4d22d4959 --- /dev/null +++ b/packages/web-components/src/image/image.ts @@ -0,0 +1,54 @@ +import { attr, FASTElement } from '@microsoft/fast-element'; +import { ImageFit, ImageShape } from './image.options.js'; + +/** + * The base class used for constucting a fluent image custom element + * @public + */ +export class Image extends FASTElement { + /** + * Image layout + * + * @public + * @remarks + * HTML attribute: block. + */ + @attr({ mode: 'boolean' }) + public block?: boolean; + /** + * Image border + * + * @public + * @remarks + * HTML attribute: border. + */ + @attr({ mode: 'boolean' }) + public bordered?: boolean; + /** + * Image shadow + * + * @public + * @remarks + * HTML attribute: shadow. + */ + @attr({ mode: 'boolean' }) + public shadow?: boolean; + /** + * Image fit + * + * @public + * @remarks + * HTML attribute: fit. + */ + @attr + public fit?: ImageFit; + /** + * Image shape + * + * @public + * @remarks + * HTML attribute: shape. + */ + @attr + public shape?: ImageShape; +} diff --git a/packages/web-components/src/image/index.ts b/packages/web-components/src/image/index.ts new file mode 100644 index 0000000000000..29839a1248865 --- /dev/null +++ b/packages/web-components/src/image/index.ts @@ -0,0 +1,5 @@ +export * from './image.js'; +export * from './image.options.js'; +export { definition as ImageDefinition } from './image.definition.js'; +export { template as ImageTemplate } from './image.template.js'; +export { styles as ImageStyles } from './image.styles.js'; diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index f259843fc5e6f..eaf2580651e94 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -2,6 +2,7 @@ export * from './accordion/index.js'; export * from './accordion-item/index.js'; export * from './badge/index.js'; export * from './counter-badge/index.js'; +export * from './image/index.js'; export * from './progress-bar/index.js'; export * from './spinner/index.js'; export * from './switch/index.js'; From 47b64494269ea194a9d3b7da961df8b057240356 Mon Sep 17 00:00:00 2001 From: Hale Rankin Date: Fri, 24 Feb 2023 16:29:55 -0800 Subject: [PATCH 041/203] Adds Divider web component (#26901) * Adds Divider component * Generates change --- ...-2500a738-206b-4f66-b5d5-c60924e40a5b.json | 7 + packages/web-components/package.json | 4 + packages/web-components/src/divider/define.ts | 4 + .../src/divider/divider.definition.ts | 17 ++ .../src/divider/divider.options.ts | 46 ++++++ .../src/divider/divider.stories.ts | 147 ++++++++++++++++++ .../src/divider/divider.styles.ts | 124 +++++++++++++++ .../src/divider/divider.template.ts | 9 ++ .../web-components/src/divider/divider.ts | 38 +++++ packages/web-components/src/divider/index.ts | 5 + packages/web-components/src/index.ts | 1 + 11 files changed, 402 insertions(+) create mode 100644 change/@fluentui-web-components-2500a738-206b-4f66-b5d5-c60924e40a5b.json create mode 100644 packages/web-components/src/divider/define.ts create mode 100644 packages/web-components/src/divider/divider.definition.ts create mode 100644 packages/web-components/src/divider/divider.options.ts create mode 100644 packages/web-components/src/divider/divider.stories.ts create mode 100644 packages/web-components/src/divider/divider.styles.ts create mode 100644 packages/web-components/src/divider/divider.template.ts create mode 100644 packages/web-components/src/divider/divider.ts create mode 100644 packages/web-components/src/divider/index.ts diff --git a/change/@fluentui-web-components-2500a738-206b-4f66-b5d5-c60924e40a5b.json b/change/@fluentui-web-components-2500a738-206b-4f66-b5d5-c60924e40a5b.json new file mode 100644 index 0000000000000..21d5f30077f2d --- /dev/null +++ b/change/@fluentui-web-components-2500a738-206b-4f66-b5d5-c60924e40a5b.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat(divider): Add divider web component", + "packageName": "@fluentui/web-components", + "email": "harankin@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 2652825beb712..14de3ce922e06 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -40,6 +40,10 @@ "types": "./dist/esm/counter-badge/define.d.ts", "default": "./dist/esm/counter-badge/define.js" }, + "./divider": { + "types": "./dist/esm/divider/define.d.ts", + "default": "./dist/esm/divider/define.js" + }, "./image": { "types": "./dist/esm/image/define.d.ts", "default": "./dist/esm/image/define.js" diff --git a/packages/web-components/src/divider/define.ts b/packages/web-components/src/divider/define.ts new file mode 100644 index 0000000000000..228db50031378 --- /dev/null +++ b/packages/web-components/src/divider/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './divider.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/divider/divider.definition.ts b/packages/web-components/src/divider/divider.definition.ts new file mode 100644 index 0000000000000..3bc3304ad0209 --- /dev/null +++ b/packages/web-components/src/divider/divider.definition.ts @@ -0,0 +1,17 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Divider } from './divider.js'; +import { template } from './divider.template.js'; +import { styles } from './divider.styles.js'; + +/** + * The Fluent Divider Element + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = Divider.compose({ + name: `${FluentDesignSystem.prefix}-divider`, + template, + styles, +}); diff --git a/packages/web-components/src/divider/divider.options.ts b/packages/web-components/src/divider/divider.options.ts new file mode 100644 index 0000000000000..9e24ccda52042 --- /dev/null +++ b/packages/web-components/src/divider/divider.options.ts @@ -0,0 +1,46 @@ +import { DividerOrientation, DividerRole, ValuesOf } from '@microsoft/fast-foundation'; + +/** + * Fast Foundation DividerRole property + * @public + */ +export { DividerRole }; + +/** + * Fast Foundation Orientation property + * @public + */ +export { DividerOrientation }; + +/** + * Align content within divider + * @public + */ +export const DividerAlignContent = { + center: 'center', + start: 'start', + end: 'end', +} as const; + +/** + * The types for DividerAlignContent + * @public + */ +export type DividerAlignContent = ValuesOf; + +/** + * DividerAppearance - divider color defined by a design token alias. + * @public + */ +export const DividerAppearance = { + strong: 'strong', + brand: 'brand', + subtle: 'subtle', + default: 'default', +} as const; + +/** + * The types for Appearance + * @public + */ +export type DividerAppearance = ValuesOf; diff --git a/packages/web-components/src/divider/divider.stories.ts b/packages/web-components/src/divider/divider.stories.ts new file mode 100644 index 0000000000000..95bb0ce140666 --- /dev/null +++ b/packages/web-components/src/divider/divider.stories.ts @@ -0,0 +1,147 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../helpers.stories.js'; +import type { Divider as FluentDivider } from './divider.js'; +import { DividerAlignContent, DividerAppearance, DividerOrientation, DividerRole } from './divider.options.js'; +import './define.js'; + +type DividerStoryArgs = Args & FluentDivider; +type DividerStoryMeta = Meta; + +const dividerTemplate = html` +
+ x.alignContent} + appearance=${x => x.appearance} + role=${x => x.role} + ?inset=${x => x.inset} + orientation=${x => x.orientation} + > + ${x => (x.content ? html`

${x.content}

` : '')} +
+
+`; + +const dividerSvgTemplate = html` +
+ + + + + +
+`; + +const dividerSvgVerticalTemplate = html` + x.role} ?inset=${x => x.inset} orientation="vertical"> + + + + +`; + +export default { + title: 'Components/Divider', + args: { + content: 'Section One', + alignContent: undefined, + appearance: undefined, + role: DividerRole.separator, + inset: false, + orientation: undefined, + }, + argTypes: { + content: { + description: 'HTML element wrapping text (e.g. `

Section One

`), Image or SVG', + table: { + defaultValue: { + summary: 'empty', + }, + }, + }, + alignContent: { + description: 'Align content', + table: { + type: { + summary: 'Fluent v9. Determines the alignment of the content within the divider.', + }, + defaultValue: { + summary: 'undefined', + }, + }, + options: Object.values(DividerAlignContent), + control: { + type: 'select', + }, + }, + appearance: { + description: 'Divider and text colors', + table: { + type: { + summary: 'Fluent v9. A divider can have one of the preset appearances.', + }, + defaultValue: { + summary: 'undefined', + }, + }, + options: Object.values(DividerAppearance), + control: { + type: 'select', + }, + }, + role: { + description: 'Set role attribute', + table: { + type: { + summary: 'Inherited from FASTDivider. Aria role for the divider.', + }, + defaultValue: { + summary: 'separator', + }, + }, + options: Object.values(DividerRole), + control: { + type: 'select', + }, + }, + inset: { + description: 'Pad the ends of divider', + table: { + type: { + summary: + 'Type: boolean. Fluent v9. Divider layout is block for strict distinctions between items, or inset for closer relationships with neighboring content.', + }, + defaultValue: { + summary: false, + }, + }, + control: 'boolean', + }, + orientation: { + description: 'Divider layout', + table: { + type: { + summary: + 'Inherited from FASTDivider. Layout can be horizontal or vertical. Adds aria-orientation to component.', + }, + defaultValue: { + summary: undefined, + }, + }, + options: Object.values(DividerOrientation), + control: { + type: 'select', + }, + }, + }, +} as DividerStoryMeta; + +export const Divider = renderComponent(dividerTemplate).bind({}); +export const DividerWithSvg = renderComponent(dividerSvgTemplate).bind({}); +export const VerticalDividerWithSvg = renderComponent(dividerSvgVerticalTemplate).bind({}); diff --git a/packages/web-components/src/divider/divider.styles.ts b/packages/web-components/src/divider/divider.styles.ts new file mode 100644 index 0000000000000..e302ab9271da0 --- /dev/null +++ b/packages/web-components/src/divider/divider.styles.ts @@ -0,0 +1,124 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + colorBrandForeground1, + colorBrandStroke1, + colorNeutralForeground1, + colorNeutralForeground2, + colorNeutralForeground3, + colorNeutralStroke1, + colorNeutralStroke2, + colorNeutralStroke3, + fontFamilyBase, + fontSizeBase200, + fontWeightRegular, + strokeWidthThin, +} from '../theme/design-tokens.js'; + +/** Divider styles + * @public + */ +export const styles = css` + ${display('flex')} + + :host::after, + :host::before { + align-self: center; + background: ${colorNeutralStroke2}; + box-sizing: border-box; + content: ''; + display: flex; + flex-grow: 1; + height: ${strokeWidthThin}; + } + + :host([inset]) { + padding: 0 12px; + } + + :host ::slotted(*) { + color: ${colorNeutralForeground2}; + font-family: ${fontFamilyBase}; + font-size: ${fontSizeBase200}; + font-weight: ${fontWeightRegular}; + margin: 0; + padding: 0 12px; + } + + :host([align-content='start'])::before, + :host([align-content='end'])::after { + flex-basis: 12px; + flex-grow: 0; + flex-shrink: 0; + } + + :host([orientation='vertical']) { + height: 100%; + min-height: 84px; + } + :host([orientation='vertical']):empty { + min-height: 20px; + } + + :host([orientation='vertical']) { + flex-direction: column; + align-items: center; + } + + :host([orientation='vertical'][inset])::before { + margin-top: 12px; + } + :host([orientation='vertical'][inset])::after { + margin-bottom: 12px; + } + + :host([orientation='vertical']):empty::before, + :host([orientation='vertical']):empty::after { + height: 10px; + min-height: 10px; + flex-grow: 0; + } + + :host([orientation='vertical'])::before, + :host([orientation='vertical'])::after { + width: ${strokeWidthThin}; + min-height: 20px; + height: 100%; + } + + :host([orientation='vertical']) ::slotted(*) { + display: flex; + flex-direction: column; + padding: 12px 0; + line-height: 20px; + } + + :host([orientation='vertical'][align-content='start'])::before { + min-height: 8px; + } + :host([orientation='vertical'][align-content='end'])::after { + min-height: 8px; + } + + :host([appearance='strong'])::before, + :host([appearance='strong'])::after { + background: ${colorNeutralStroke1}; + } + :host([appearance='strong']) ::slotted(*) { + color: ${colorNeutralForeground1}; + } + :host([appearance='brand'])::before, + :host([appearance='brand'])::after { + background: ${colorBrandStroke1}; + } + :host([appearance='brand']) ::slotted(*) { + color: ${colorBrandForeground1}; + } + :host([appearance='subtle'])::before, + :host([appearance='subtle'])::after { + background: ${colorNeutralStroke3}; + } + :host([appearance='subtle']) ::slotted(*) { + color: ${colorNeutralForeground3}; + } +`; diff --git a/packages/web-components/src/divider/divider.template.ts b/packages/web-components/src/divider/divider.template.ts new file mode 100644 index 0000000000000..eecca0cb4535c --- /dev/null +++ b/packages/web-components/src/divider/divider.template.ts @@ -0,0 +1,9 @@ +import { ElementViewTemplate } from '@microsoft/fast-element'; +import { dividerTemplate } from '@microsoft/fast-foundation'; +import type { Divider } from './divider.js'; + +/** + * Template for the Divider component + * @public + */ +export const template: ElementViewTemplate = dividerTemplate(); diff --git a/packages/web-components/src/divider/divider.ts b/packages/web-components/src/divider/divider.ts new file mode 100644 index 0000000000000..9c208437d590a --- /dev/null +++ b/packages/web-components/src/divider/divider.ts @@ -0,0 +1,38 @@ +import { attr } from '@microsoft/fast-element'; +import { FASTDivider } from '@microsoft/fast-foundation'; +import { DividerAlignContent, DividerAppearance } from './divider.options.js'; + +/** + * @class Divider component + * + * @remarks + * This class extends the FASTDivider. A divider groups sections of content to create visual rhythm and hierarchy. Use dividers along with spacing and headers to organize content in your layout. + */ +export class Divider extends FASTDivider { + /** + * @property alignContent + * @default center + * @remarks + * Determines the alignment of the content within the divider. Select from start or end. When not specified, the content will be aligned to the center. + */ + @attr({ attribute: 'align-content' }) + public alignContent?: DividerAlignContent; + + /** + * @property appearance + * @default default + * @remarks + * A divider can have one of the preset appearances. Select from strong, brand, subtle. When not specified, the divider has its default appearance. + */ + @attr + public appearance?: DividerAppearance; + + /** + * @property inset + * @default false + * @remarks + * Adds padding to the beginning and end of the divider. + */ + @attr({ mode: 'boolean' }) + public inset?: boolean; +} diff --git a/packages/web-components/src/divider/index.ts b/packages/web-components/src/divider/index.ts new file mode 100644 index 0000000000000..5ee2dd0fcaf33 --- /dev/null +++ b/packages/web-components/src/divider/index.ts @@ -0,0 +1,5 @@ +export * from './divider.js'; +export * from './divider.options.js'; +export { definition as DividerDefinition } from './divider.definition.js'; +export { template as DividerTemplate } from './divider.template.js'; +export { styles as DividerStyles } from './divider.styles.js'; diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index eaf2580651e94..f8394d0a1cf52 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -2,6 +2,7 @@ export * from './accordion/index.js'; export * from './accordion-item/index.js'; export * from './badge/index.js'; export * from './counter-badge/index.js'; +export * from './divider/index.js'; export * from './image/index.js'; export * from './progress-bar/index.js'; export * from './spinner/index.js'; From a27c73f1a6c62f30c5c4ac992ffc5f6fff0089b5 Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Fri, 24 Feb 2023 17:09:43 -0800 Subject: [PATCH 042/203] (web-components): add avatar as a new Fluent 2 aligned component (#26729) * add avatar as a new component * add export path * update helpers path in avatar stories * create public static value for named colors * update styles to support any slotted badge * add size 16 styles and stories * update animations to use tokens * add support for prefers reduced motion on active and inactive transitions * change set to generate for color and initials fns * add large badge styles * remove unnecessary badge cchange handlers * fix brand color in dark mode with static inverted value * update change file * remove unnecessary lifecycle event * add avatar readme for react deltas * update attributes as optional * update api report --- ...-1c73e6e8-61a0-46c8-b69e-0820f5a2488d.json | 7 + packages/web-components/.eslintrc.json | 1 + packages/web-components/docs/api-report.md | 322 ++++++++++ packages/web-components/package.json | 4 + packages/web-components/src/avatar/README.md | 59 ++ .../src/avatar/avatar.definition.ts | 17 + .../src/avatar/avatar.options.ts | 125 ++++ .../src/avatar/avatar.stories.ts | 194 ++++++ .../src/avatar/avatar.styles.ts | 577 ++++++++++++++++++ .../src/avatar/avatar.template.ts | 31 + packages/web-components/src/avatar/avatar.ts | 158 +++++ packages/web-components/src/avatar/define.ts | 4 + packages/web-components/src/avatar/index.ts | 5 + packages/web-components/src/index.ts | 1 + .../web-components/src/utils/get-initials.ts | 110 ++++ 15 files changed, 1615 insertions(+) create mode 100644 change/@fluentui-web-components-1c73e6e8-61a0-46c8-b69e-0820f5a2488d.json create mode 100644 packages/web-components/src/avatar/README.md create mode 100644 packages/web-components/src/avatar/avatar.definition.ts create mode 100644 packages/web-components/src/avatar/avatar.options.ts create mode 100644 packages/web-components/src/avatar/avatar.stories.ts create mode 100644 packages/web-components/src/avatar/avatar.styles.ts create mode 100644 packages/web-components/src/avatar/avatar.template.ts create mode 100644 packages/web-components/src/avatar/avatar.ts create mode 100644 packages/web-components/src/avatar/define.ts create mode 100644 packages/web-components/src/avatar/index.ts create mode 100644 packages/web-components/src/utils/get-initials.ts diff --git a/change/@fluentui-web-components-1c73e6e8-61a0-46c8-b69e-0820f5a2488d.json b/change/@fluentui-web-components-1c73e6e8-61a0-46c8-b69e-0820f5a2488d.json new file mode 100644 index 0000000000000..ab3341afdf7ad --- /dev/null +++ b/change/@fluentui-web-components-1c73e6e8-61a0-46c8-b69e-0820f5a2488d.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat(avatar): add Avatar web component", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/.eslintrc.json b/packages/web-components/.eslintrc.json index ca5b46cb7c91c..29a022348e612 100644 --- a/packages/web-components/.eslintrc.json +++ b/packages/web-components/.eslintrc.json @@ -18,6 +18,7 @@ "no-prototype-builtins": "off", "no-fallthrough": "off", "no-unexpected-multiline": "off", + "no-useless-escape": "off", "import/order": "error", "sort-imports": [ "error", diff --git a/packages/web-components/docs/api-report.md b/packages/web-components/docs/api-report.md index 4563c8b9e70f4..2e81845851dce 100644 --- a/packages/web-components/docs/api-report.md +++ b/packages/web-components/docs/api-report.md @@ -5,18 +5,234 @@ ```ts import { CSSDesignToken } from '@microsoft/fast-foundation'; +import { DividerOrientation } from '@microsoft/fast-foundation'; +import { DividerRole } from '@microsoft/fast-foundation'; import { ElementStyles } from '@microsoft/fast-element'; import { ElementViewTemplate } from '@microsoft/fast-element'; +import { FASTAccordion } from '@microsoft/fast-foundation'; +import { FASTAccordionItem } from '@microsoft/fast-foundation'; +import { FASTDivider } from '@microsoft/fast-foundation'; import { FASTElement } from '@microsoft/fast-element'; import { FASTElementDefinition } from '@microsoft/fast-element'; import { FASTProgress } from '@microsoft/fast-foundation'; import { FASTProgressRing } from '@microsoft/fast-foundation'; +import { FASTSwitch } from '@microsoft/fast-foundation'; import { StartEnd } from '@microsoft/fast-foundation'; import { StartEndOptions } from '@microsoft/fast-foundation'; import { StaticallyComposableHTML } from '@microsoft/fast-foundation'; import type { Theme } from '@fluentui/tokens'; import { ValuesOf } from '@microsoft/fast-foundation'; +// @public +export class Accordion extends FASTAccordion { +} + +// @public +export const accordionDefinition: FASTElementDefinition; + +// Warning: (ae-internal-missing-underscore) The name "AccordionItem" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal (undocumented) +export class AccordionItem extends FASTAccordionItem { + // @public + block: boolean; + // @public + expandIconPosition: AccordionItemExpandIconPosition; + // @public + size: AccordionItemSize; +} + +// Warning: (ae-incompatible-release-tags) The symbol "definition" is marked as @public, but its signature references "AccordionItem" which is marked as @internal +// +// @public +export const accordionItemDefinition: FASTElementDefinition; + +// @public +export const AccordionItemExpandIconPosition: { + readonly start: "start"; + readonly end: "end"; +}; + +// @public +export type AccordionItemExpandIconPosition = ValuesOf; + +// @public +export const AccordionItemSize: { + readonly small: "small"; + readonly medium: "medium"; + readonly large: "large"; + readonly extraLarge: "extra-large"; +}; + +// @public +export type AccordionItemSize = ValuesOf; + +// @public (undocumented) +export const accordionItemStyles: ElementStyles; + +// Warning: (ae-incompatible-release-tags) The symbol "template" is marked as @public, but its signature references "AccordionItem" which is marked as @internal +// +// @public +export const accordionItemTemplate: ElementViewTemplate; + +// @public (undocumented) +export const accordionStyles: ElementStyles; + +// @public (undocumented) +export const accordionTemplate: ElementViewTemplate; + +// @public +export class Avatar extends FASTElement { + active?: AvatarActive | undefined; + appearance?: AvatarAppearance | undefined; + color?: AvatarColor; + colorId?: AvatarNamedColor | undefined; + static colors: ("anchor" | "dark-red" | "cranberry" | "red" | "pumpkin" | "peach" | "marigold" | "gold" | "brass" | "brown" | "forest" | "seafoam" | "dark-green" | "light-teal" | "teal" | "steel" | "blue" | "royal-blue" | "cornflower" | "navy" | "lavender" | "purple" | "grape" | "lilac" | "pink" | "magenta" | "plum" | "beige" | "mink" | "platinum")[]; + // @internal + generateColor(): AvatarColor | void; + // @internal + generateInitials(): string | void; + initials?: string | undefined; + name?: string | undefined; + shape?: AvatarShape | undefined; + size?: AvatarSize | undefined; +} + +// @public +export const AvatarActive: { + readonly active: "active"; + readonly inactive: "inactive"; +}; + +// @public +export type AvatarActive = ValuesOf; + +// @public +export const AvatarAppearance: { + readonly ring: "ring"; + readonly shadow: "shadow"; + readonly ringShadow: "ring-shadow"; +}; + +// @public +export type AvatarAppearance = ValuesOf; + +// @public +export const AvatarColor: { + readonly darkRed: "dark-red"; + readonly cranberry: "cranberry"; + readonly red: "red"; + readonly pumpkin: "pumpkin"; + readonly peach: "peach"; + readonly marigold: "marigold"; + readonly gold: "gold"; + readonly brass: "brass"; + readonly brown: "brown"; + readonly forest: "forest"; + readonly seafoam: "seafoam"; + readonly darkGreen: "dark-green"; + readonly lightTeal: "light-teal"; + readonly teal: "teal"; + readonly steel: "steel"; + readonly blue: "blue"; + readonly royalBlue: "royal-blue"; + readonly cornflower: "cornflower"; + readonly navy: "navy"; + readonly lavender: "lavender"; + readonly purple: "purple"; + readonly grape: "grape"; + readonly lilac: "lilac"; + readonly pink: "pink"; + readonly magenta: "magenta"; + readonly plum: "plum"; + readonly beige: "beige"; + readonly mink: "mink"; + readonly platinum: "platinum"; + readonly anchor: "anchor"; + readonly neutral: "neutral"; + readonly brand: "brand"; + readonly colorful: "colorful"; +}; + +// @public +export type AvatarColor = ValuesOf; + +// @public +export const AvatarDefinition: FASTElementDefinition; + +// @public +export const AvatarNamedColor: { + readonly darkRed: "dark-red"; + readonly cranberry: "cranberry"; + readonly red: "red"; + readonly pumpkin: "pumpkin"; + readonly peach: "peach"; + readonly marigold: "marigold"; + readonly gold: "gold"; + readonly brass: "brass"; + readonly brown: "brown"; + readonly forest: "forest"; + readonly seafoam: "seafoam"; + readonly darkGreen: "dark-green"; + readonly lightTeal: "light-teal"; + readonly teal: "teal"; + readonly steel: "steel"; + readonly blue: "blue"; + readonly royalBlue: "royal-blue"; + readonly cornflower: "cornflower"; + readonly navy: "navy"; + readonly lavender: "lavender"; + readonly purple: "purple"; + readonly grape: "grape"; + readonly lilac: "lilac"; + readonly pink: "pink"; + readonly magenta: "magenta"; + readonly plum: "plum"; + readonly beige: "beige"; + readonly mink: "mink"; + readonly platinum: "platinum"; + readonly anchor: "anchor"; +}; + +// @public +export type AvatarNamedColor = ValuesOf; + +// @public +export const AvatarShape: { + readonly circular: "circular"; + readonly square: "square"; +}; + +// @public +export type AvatarShape = ValuesOf; + +// @public +export const AvatarSize: { + readonly _16: 16; + readonly _20: 20; + readonly _24: 24; + readonly _28: 28; + readonly _32: 32; + readonly _36: 36; + readonly _40: 40; + readonly _48: 48; + readonly _56: 56; + readonly _64: 64; + readonly _72: 72; + readonly _96: 96; + readonly _120: 120; + readonly _128: 128; +}; + +// @public +export type AvatarSize = ValuesOf; + +// @public +export const AvatarStyles: ElementStyles; + +// @public (undocumented) +export const AvatarTemplate: ElementViewTemplate; + // Warning: (ae-internal-mixed-release-tag) Mixed release tags are not allowed for "Badge" because one of its declarations is marked as @internal // // @public @@ -1101,6 +1317,50 @@ export const curveEasyEaseMax: CSSDesignToken; // @public (undocumented) export const curveLinear: CSSDesignToken; +// @public +export const definition: FASTElementDefinition; + +// @public +export class Divider extends FASTDivider { + alignContent?: DividerAlignContent; + appearance?: DividerAppearance; + inset?: boolean; +} + +// @public +export const DividerAlignContent: { + readonly center: "center"; + readonly start: "start"; + readonly end: "end"; +}; + +// @public +export type DividerAlignContent = ValuesOf; + +// @public +export const DividerAppearance: { + readonly strong: "strong"; + readonly brand: "brand"; + readonly subtle: "subtle"; + readonly default: "default"; +}; + +// @public +export type DividerAppearance = ValuesOf; + +// @public +export const DividerDefinition: FASTElementDefinition; + +export { DividerOrientation } + +export { DividerRole } + +// @public +export const DividerStyles: ElementStyles; + +// @public +export const DividerTemplate: ElementViewTemplate; + // @public (undocumented) export const durationFast: CSSDesignToken; @@ -1173,6 +1433,47 @@ export const fontWeightRegular: CSSDesignToken; // @public (undocumented) export const fontWeightSemibold: CSSDesignToken; +// @public +class Image_2 extends FASTElement { + block?: boolean; + bordered?: boolean; + fit?: ImageFit; + shadow?: boolean; + shape?: ImageShape; +} +export { Image_2 as Image } + +// @public +export const ImageDefinition: FASTElementDefinition; + +// @public +export const ImageFit: { + readonly none: "none"; + readonly center: "center"; + readonly contain: "contain"; + readonly cover: "cover"; + readonly default: "default"; +}; + +// @public +export type ImageFit = ValuesOf; + +// @public +export const ImageShape: { + readonly circular: "circular"; + readonly rounded: "rounded"; + readonly square: "square"; +}; + +// @public (undocumented) +export type ImageShape = ValuesOf; + +// @public +export const ImageStyles: ElementStyles; + +// @public +export const ImageTemplate: ElementViewTemplate; + // @public (undocumented) export const lineHeightBase100: CSSDesignToken; @@ -1403,6 +1704,27 @@ export const strokeWidthThickest: CSSDesignToken; // @public (undocumented) export const strokeWidthThin: CSSDesignToken; +// @public (undocumented) +export class Switch extends FASTSwitch { + labelPosition: SwitchLabelPosition | undefined; +} + +// @public +export const SwitchLabelPosition: { + readonly above: "above"; + readonly after: "after"; + readonly before: "before"; +}; + +// @public +export type SwitchLabelPosition = ValuesOf; + +// @public (undocumented) +export const switchStyles: ElementStyles; + +// @public (undocumented) +export const switchTemplate: ElementViewTemplate; + // @public class Text_2 extends FASTElement { align: TextAlign; diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 14de3ce922e06..7093c1856539d 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -32,6 +32,10 @@ "types": "./dist/esm/accordion-item/define.d.ts", "default": "./dist/esm/accordion-item/define.js" }, + "./avatar": { + "types": "./dist/esm/avatar/define.d.ts", + "default": "./dist/esm/avatar/define.js" + }, "./badge": { "types": "./dist/esm/badge/define.d.ts", "default": "./dist/esm/badge/define.js" diff --git a/packages/web-components/src/avatar/README.md b/packages/web-components/src/avatar/README.md new file mode 100644 index 0000000000000..0aea250cdf8db --- /dev/null +++ b/packages/web-components/src/avatar/README.md @@ -0,0 +1,59 @@ +# Avatar + +The Avatar component represents a person or entity. It displays the person's image, initials, or an icon, and can be either circular or square. + +## **Design Spec** + +[Link to Avatar in Figma](https://www.figma.com/file/3SlxyaJA3tpLs5rVZ4oTVj/Avatar?node-id=0%3A1&t=Ugsg41JLdURbxd7i-1) + +
+ +## **Engineering Spec** + +Fluent WC3 Avatar has feature parity with the Fluent UI React 9 Accordion implementation but not direct parity. + +
+ +## Class: `Avatar` + +
+ +### **Component Name** + +`` + +
+ +## **Preparation** + +
+ +### **Fluent Web Component v3 v.s Fluent React 9** + +
+ +**Component and Slot Mapping** + +| Fluent UI React 9 | Fluent Web Components 3 | +| ----------------- | ----------------------- | +| `` | `` | + +
+ +**Property Mapping** +| Fluent UI React 9 | Fluent Web Components 3 | Description of difference | +| ------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------- | +| `idForColor: string`| `colorId: string` | both are strings, the delta here is primarily verbosity. In web components attributes need to follow HTML syntax for attributes. The property of `colorId` maps to `color-id`. Were we to map directly we would have an attribute of `id-for-color` which seems overly verbose. Almost all HTML attributes are at max hyphenated once. This proposes an attribute which is less verbose and only requires a single `-`. | +| `size` | `size` | | +| `shape` | `shape` | +| `active` | `active` | The only delta here is that the web components are aligning to the resolved RFC to use `undefined` for fields which are intended to "unset" attributes | +| `activeAppearance` | `appearance` | The delta here is semantic only, unless we need to reserve the appearance namespace, brevity seems preferred here | +| `name` | `name` | +| `initials` | `initials` | + +**Additional Deltas:** + +The FUIR9 implementation seems to utilize several "slots", whereas with the web component implementation includes two primary slots. + +1. Default slot - When a name or initials is provided, the default slot projects the initials generated via name or initials. If an image is slotted into the default slot, the image will be shown. If an SVG is slotted into the default slot an SVG will project overriding any other value. If name and initials are not provided and nothing is slotted, the default avatar svg is projected. +2. Badge - The slot for the badge diff --git a/packages/web-components/src/avatar/avatar.definition.ts b/packages/web-components/src/avatar/avatar.definition.ts new file mode 100644 index 0000000000000..6f076756e5860 --- /dev/null +++ b/packages/web-components/src/avatar/avatar.definition.ts @@ -0,0 +1,17 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Avatar } from './avatar.js'; +import { styles } from './avatar.styles.js'; +import { template } from './avatar.template.js'; + +/** + * The Fluent Avatar Element. + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = Avatar.compose({ + name: `${FluentDesignSystem.prefix}-avatar`, + template, + styles, +}); diff --git a/packages/web-components/src/avatar/avatar.options.ts b/packages/web-components/src/avatar/avatar.options.ts new file mode 100644 index 0000000000000..8d6db2d8c7a40 --- /dev/null +++ b/packages/web-components/src/avatar/avatar.options.ts @@ -0,0 +1,125 @@ +import { ValuesOf } from '@microsoft/fast-foundation'; + +/** + * The Avatar "active" state + */ +export const AvatarActive = { + active: 'active', + inactive: 'inactive', +} as const; + +/** + * The types of Avatar active state + */ +export type AvatarActive = ValuesOf; + +/** + * The Avatar Shape + */ +export const AvatarShape = { + circular: 'circular', + square: 'square', +} as const; + +/** + * The types of Avatar Shape + */ +export type AvatarShape = ValuesOf; + +/** + * The Avatar Appearance when "active" + */ +export const AvatarAppearance = { + ring: 'ring', + shadow: 'shadow', + ringShadow: 'ring-shadow', +} as const; + +/** + * The appearance when "active" + */ +export type AvatarAppearance = ValuesOf; + +/** + * A specific named color for the Avatar + */ +export const AvatarNamedColor = { + darkRed: 'dark-red', + cranberry: 'cranberry', + red: 'red', + pumpkin: 'pumpkin', + peach: 'peach', + marigold: 'marigold', + gold: 'gold', + brass: 'brass', + brown: 'brown', + forest: 'forest', + seafoam: 'seafoam', + darkGreen: 'dark-green', + lightTeal: 'light-teal', + teal: 'teal', + steel: 'steel', + blue: 'blue', + royalBlue: 'royal-blue', + cornflower: 'cornflower', + navy: 'navy', + lavender: 'lavender', + purple: 'purple', + grape: 'grape', + lilac: 'lilac', + pink: 'pink', + magenta: 'magenta', + plum: 'plum', + beige: 'beige', + mink: 'mink', + platinum: 'platinum', + anchor: 'anchor', +} as const; + +/** + * An avatar can be one of named colors + * @public + */ +export type AvatarNamedColor = ValuesOf; + +/** + * Supported Avatar colors + */ +export const AvatarColor = { + neutral: 'neutral', + brand: 'brand', + colorful: 'colorful', + ...AvatarNamedColor, +} as const; + +/** + * The Avatar Color + */ +export type AvatarColor = ValuesOf; + +/** + * The Avatar Sizes + * @public + */ +export const AvatarSize = { + _16: 16, + _20: 20, + _24: 24, + _28: 28, + _32: 32, + _36: 36, + _40: 40, + _48: 48, + _56: 56, + _64: 64, + _72: 72, + _96: 96, + _120: 120, + _128: 128, +} as const; + +/** + * A Avatar can be on of several preset sizes. + * @public + */ +export type AvatarSize = ValuesOf; diff --git a/packages/web-components/src/avatar/avatar.stories.ts b/packages/web-components/src/avatar/avatar.stories.ts new file mode 100644 index 0000000000000..8765138662cca --- /dev/null +++ b/packages/web-components/src/avatar/avatar.stories.ts @@ -0,0 +1,194 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../helpers.stories.js'; +import type { Avatar as FluentAvatar } from './avatar.js'; +import { AvatarActive, AvatarAppearance, AvatarColor, AvatarShape, AvatarSize } from './avatar.options.js'; +import './define.js'; + +type AvatarStoryArgs = Args & FluentAvatar; +type AvatarStoryMeta = Meta; + +const storyTemplate = html` + +`; + +export default { + title: 'Components/Avatar', + argTypes: { + active: { + options: Object.values(AvatarActive), + control: { + type: 'select', + }, + }, + appearance: { + options: Object.values(AvatarAppearance), + control: { + type: 'select', + }, + }, + color: { + options: Object.values(AvatarColor), + control: { + type: 'select', + }, + }, + initials: { + control: 'text', + }, + name: { + control: 'text', + }, + shape: { + options: Object.values(AvatarShape), + control: { + type: 'select', + }, + }, + size: { + options: Object.values(AvatarSize), + control: { + type: 'select', + }, + }, + }, +} as AvatarStoryMeta; + +export const Avatar = renderComponent(storyTemplate).bind({}); + +export const Image = renderComponent(html` + +`); + +export const Icon = renderComponent(html` + +`); + +export const Badge = renderComponent(html` `); + +export const ColorBrand = renderComponent(html``); + +export const Color = renderComponent(html` +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+`); + +export const Colorful = renderComponent(html` +
+ + + + + + + + + + + + +
+`); + +export const Shape = renderComponent(html` + + +`); + +export const Active = renderComponent(html` +
+ U + A + I +
+
+`); + +export const ActiveAppearance = renderComponent(html` +
+ R + S + RS +
+`); + +export const CustomInitials = renderComponent(html` `); + +export const Size = renderComponent(html` +
+ 16 + 20 + 24 + 28 + 32 + 36 + 40 + 48 + 56 + 64 + 72 + 96 + 120 + 128 +
+`); diff --git a/packages/web-components/src/avatar/avatar.styles.ts b/packages/web-components/src/avatar/avatar.styles.ts new file mode 100644 index 0000000000000..50604d331c711 --- /dev/null +++ b/packages/web-components/src/avatar/avatar.styles.ts @@ -0,0 +1,577 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + borderRadiusCircular, + borderRadiusLarge, + borderRadiusMedium, + borderRadiusSmall, + borderRadiusXLarge, + colorBrandBackgroundStatic, + colorNeutralBackground1, + colorNeutralBackground6, + colorNeutralForeground3, + colorNeutralForegroundStaticInverted, + colorPaletteAnchorBackground2, + colorPaletteAnchorForeground2, + colorPaletteBeigeBackground2, + colorPaletteBeigeForeground2, + colorPaletteBlueBackground2, + colorPaletteBlueForeground2, + colorPaletteBrassBackground2, + colorPaletteBrassForeground2, + colorPaletteBrownBackground2, + colorPaletteBrownForeground2, + colorPaletteCornflowerBackground2, + colorPaletteCornflowerForeground2, + colorPaletteCranberryBackground2, + colorPaletteCranberryForeground2, + colorPaletteDarkGreenBackground2, + colorPaletteDarkGreenForeground2, + colorPaletteDarkRedBackground2, + colorPaletteDarkRedForeground2, + colorPaletteForestBackground2, + colorPaletteForestForeground2, + colorPaletteGoldBackground2, + colorPaletteGoldForeground2, + colorPaletteGrapeBackground2, + colorPaletteGrapeForeground2, + colorPaletteLavenderBackground2, + colorPaletteLavenderForeground2, + colorPaletteLightTealBackground2, + colorPaletteLightTealForeground2, + colorPaletteLilacBackground2, + colorPaletteLilacForeground2, + colorPaletteMagentaBackground2, + colorPaletteMagentaForeground2, + colorPaletteMarigoldBackground2, + colorPaletteMarigoldForeground2, + colorPaletteMinkBackground2, + colorPaletteMinkForeground2, + colorPaletteNavyBackground2, + colorPaletteNavyForeground2, + colorPalettePeachBackground2, + colorPalettePeachForeground2, + colorPalettePinkBackground2, + colorPalettePinkForeground2, + colorPalettePlatinumBackground2, + colorPalettePlatinumForeground2, + colorPalettePlumBackground2, + colorPalettePlumForeground2, + colorPalettePumpkinBackground2, + colorPalettePumpkinForeground2, + colorPalettePurpleBackground2, + colorPalettePurpleForeground2, + colorPaletteRedBackground2, + colorPaletteRedForeground2, + colorPaletteRoyalBlueBackground2, + colorPaletteRoyalBlueForeground2, + colorPaletteSeafoamBackground2, + colorPaletteSeafoamForeground2, + colorPaletteSteelBackground2, + colorPaletteSteelForeground2, + colorPaletteTealBackground2, + colorPaletteTealForeground2, + curveAccelerateMax, + curveAccelerateMid, + curveAccelerateMin, + curveDecelerateMax, + curveDecelerateMid, + curveDecelerateMin, + curveEasyEase, + curveEasyEaseMax, + curveLinear, + durationFaster, + durationSlower, + durationUltraSlow, + fontFamilyBase, + fontSizeBase100, + fontSizeBase200, + fontSizeBase300, + fontSizeBase400, + fontSizeBase500, + fontSizeBase600, + fontWeightRegular, + fontWeightSemibold, + shadow16, + shadow28, + shadow4, + shadow8, + strokeWidthThick, + strokeWidthThicker, + strokeWidthThickest, + strokeWidthThin, +} from '../theme/design-tokens.js'; + +const animations = { + fastOutSlowInMax: curveDecelerateMax, + fastOutSlowInMid: curveDecelerateMid, + fastOutSlowInMin: curveDecelerateMin, + slowOutFastInMax: curveAccelerateMax, + slowOutFastInMid: curveAccelerateMid, + slowOutFastInMin: curveAccelerateMin, + fastEase: curveEasyEaseMax, + normalEase: curveEasyEase, + nullEasing: curveLinear, +}; + +/** Avatar styles + * @public + */ +export const styles = css` + ${display('inline-flex')} :host { + position: relative; + align-items: center; + justify-content: center; + flex-shrink: 0; + width: 32px; + height: 32px; + font-family: ${fontFamilyBase}; + font-weight: ${fontWeightSemibold}; + font-size: ${fontSizeBase300}; + border-radius: ${borderRadiusCircular}; + color: ${colorNeutralForeground3}; + background-color: ${colorNeutralBackground6}; + } + + .default-icon, + ::slotted(svg) { + width: 20px; + height: 20px; + font-size: 20px; + } + + ::slotted(img) { + box-sizing: border-box; + width: 100%; + height: 100%; + border-radius: ${borderRadiusCircular}; + } + + ::slotted([slot='badge']) { + position: absolute; + bottom: 0; + right: 0; + box-shadow: 0 0 0 ${strokeWidthThin} ${colorNeutralBackground1}; + } + + :host([size='64']) ::slotted([slot='badge']), + :host([size='72']) ::slotted([slot='badge']), + :host([size='96']) ::slotted([slot='badge']), + :host([size='120']) ::slotted([slot='badge']), + :host([size='128']) ::slotted([slot='badge']) { + box-shadow: 0 0 0 ${strokeWidthThick} ${colorNeutralBackground1}; + } + + :host([size='16']), + :host([size='20']), + :host([size='24']) { + font-size: ${fontSizeBase100}; + font-weight: ${fontWeightRegular}; + } + + :host([size='16']) { + width: 16px; + height: 16px; + } + + :host([size='20']) { + width: 20px; + height: 20px; + } + + :host([size='24']) { + width: 24px; + height: 24px; + } + + :host([size='16']) .default-icon, + :host([size='16']) ::slotted(svg) { + width: 12px; + height: 12px; + font-size: 12px; + } + + :host([size='20']) .default-icon, + :host([size='24']) .default-icon, + :host([size='20']) ::slotted(svg), + :host([size='24']) ::slotted(svg) { + width: 16px; + height: 16px; + font-size: 16px; + } + + :host([size='28']) { + width: 28px; + height: 28px; + font-size: ${fontSizeBase200}; + } + + :host([size='36']) { + width: 36px; + height: 36px; + } + + :host([size='40']) { + width: 40px; + height: 40px; + } + + :host([size='48']), + :host([size='56']) { + font-size: ${fontSizeBase400}; + } + + :host([size='48']) { + width: 48px; + height: 48px; + } + + :host([size='48']) .default-icon, + :host([size='48']) ::slotted(svg) { + width: 24px; + height: 24px; + font-size: 24px; + } + + :host([size='56']) { + width: 56px; + height: 56px; + } + + :host([size='56']) .default-icon, + :host([size='56']) ::slotted(svg) { + width: 28px; + height: 28px; + font-size: 28px; + } + + :host([size='64']), + :host([size='72']), + :host([size='96']) { + font-size: ${fontSizeBase500}; + } + + :host([size='64']) .default-icon, + :host([size='72']) .default-icon, + :host([size='64']) ::slotted(svg), + :host([size='72']) ::slotted(svg) { + width: 32px; + height: 32px; + font-size: 32px; + } + + :host([size='64']) { + width: 64px; + height: 64px; + } + + :host([size='72']) { + width: 72px; + height: 72px; + } + + :host([size='96']) { + width: 96px; + height: 96px; + } + + :host([size='96']) .default-icon, + :host([size='120']) .default-icon, + :host([size='128']) .default-icon, + :host([size='96']) ::slotted(svg), + :host([size='120']) ::slotted(svg), + :host([size='128']) ::slotted(svg) { + width: 48px; + height: 48px; + font-size: 48px; + } + + :host([size='120']), + :host([size='128']) { + font-size: ${fontSizeBase600}; + } + + :host([size='120']) { + width: 120px; + height: 120px; + } + + :host([size='128']) { + width: 128px; + height: 128px; + } + + :host([shape='square']) { + border-radius: ${borderRadiusMedium}; + } + + :host([shape='square'][size='20']), + :host([shape='square'][size='24']) { + border-radius: ${borderRadiusSmall}; + } + + :host([shape='square'][size='56']), + :host([shape='square'][size='64']), + :host([shape='square'][size='72']) { + border-radius: ${borderRadiusLarge}; + } + :host([shape='square'][size='96']), + :host([shape='square'][size='120']), + :host([shape='square'][size='128']) { + border-radius: ${borderRadiusXLarge}; + } + + :host([data-color='brand']) { + color: ${colorNeutralForegroundStaticInverted}; + background-color: ${colorBrandBackgroundStatic}; + } + + :host([data-color='dark-red']) { + color: ${colorPaletteDarkRedForeground2}; + background-color: ${colorPaletteDarkRedBackground2}; + } + + :host([data-color='cranberry']) { + color: ${colorPaletteCranberryForeground2}; + background-color: ${colorPaletteCranberryBackground2}; + } + + :host([data-color='red']) { + color: ${colorPaletteRedForeground2}; + background-color: ${colorPaletteRedBackground2}; + } + + :host([data-color='pumpkin']) { + color: ${colorPalettePumpkinForeground2}; + background-color: ${colorPalettePumpkinBackground2}; + } + + :host([data-color='peach']) { + color: ${colorPalettePeachForeground2}; + background-color: ${colorPalettePeachBackground2}; + } + + :host([data-color='marigold']) { + color: ${colorPaletteMarigoldForeground2}; + background-color: ${colorPaletteMarigoldBackground2}; + } + + :host([data-color='gold']) { + color: ${colorPaletteGoldForeground2}; + background-color: ${colorPaletteGoldBackground2}; + } + + :host([data-color='brass']) { + color: ${colorPaletteBrassForeground2}; + background-color: ${colorPaletteBrassBackground2}; + } + + :host([data-color='brown']) { + color: ${colorPaletteBrownForeground2}; + background-color: ${colorPaletteBrownBackground2}; + } + + :host([data-color='forest']) { + color: ${colorPaletteForestForeground2}; + background-color: ${colorPaletteForestBackground2}; + } + + :host([data-color='seafoam']) { + color: ${colorPaletteSeafoamForeground2}; + background-color: ${colorPaletteSeafoamBackground2}; + } + + :host([data-color='dark-green']) { + color: ${colorPaletteDarkGreenForeground2}; + background-color: ${colorPaletteDarkGreenBackground2}; + } + + :host([data-color='light-teal']) { + color: ${colorPaletteLightTealForeground2}; + background-color: ${colorPaletteLightTealBackground2}; + } + + :host([data-color='teal']) { + color: ${colorPaletteTealForeground2}; + background-color: ${colorPaletteTealBackground2}; + } + + :host([data-color='steel']) { + color: ${colorPaletteSteelForeground2}; + background-color: ${colorPaletteSteelBackground2}; + } + + :host([data-color='blue']) { + color: ${colorPaletteBlueForeground2}; + background-color: ${colorPaletteBlueBackground2}; + } + + :host([data-color='royal-blue']) { + color: ${colorPaletteRoyalBlueForeground2}; + background-color: ${colorPaletteRoyalBlueBackground2}; + } + + :host([data-color='cornflower']) { + color: ${colorPaletteCornflowerForeground2}; + background-color: ${colorPaletteCornflowerBackground2}; + } + + :host([data-color='navy']) { + color: ${colorPaletteNavyForeground2}; + background-color: ${colorPaletteNavyBackground2}; + } + + :host([data-color='lavender']) { + color: ${colorPaletteLavenderForeground2}; + background-color: ${colorPaletteLavenderBackground2}; + } + + :host([data-color='purple']) { + color: ${colorPalettePurpleForeground2}; + background-color: ${colorPalettePurpleBackground2}; + } + + :host([data-color='grape']) { + color: ${colorPaletteGrapeForeground2}; + background-color: ${colorPaletteGrapeBackground2}; + } + + :host([data-color='lilac']) { + color: ${colorPaletteLilacForeground2}; + background-color: ${colorPaletteLilacBackground2}; + } + + :host([data-color='pink']) { + color: ${colorPalettePinkForeground2}; + background-color: ${colorPalettePinkBackground2}; + } + + :host([data-color='magenta']) { + color: ${colorPaletteMagentaForeground2}; + background-color: ${colorPaletteMagentaBackground2}; + } + + :host([data-color='plum']) { + color: ${colorPalettePlumForeground2}; + background-color: ${colorPalettePlumBackground2}; + } + + :host([data-color='beige']) { + color: ${colorPaletteBeigeForeground2}; + background-color: ${colorPaletteBeigeBackground2}; + } + + :host([data-color='mink']) { + color: ${colorPaletteMinkForeground2}; + background-color: ${colorPaletteMinkBackground2}; + } + + :host([data-color='platinum']) { + color: ${colorPalettePlatinumForeground2}; + background-color: ${colorPalettePlatinumBackground2}; + } + + :host([data-color='anchor']) { + color: ${colorPaletteAnchorForeground2}; + background-color: ${colorPaletteAnchorBackground2}; + } + + :host([active]) { + /* Work-around for text pixel snapping at the end of the animation */ + transform: perspective(1px); + transition-property: transform, opacity; + transition-duration: ${durationUltraSlow}, ${durationFaster}; + transition-delay: ${animations.fastEase}, ${animations.nullEasing}; + } + + :host([active])::before { + content: ''; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + border-radius: inherit; + transition-property: margin, opacity; + transition-duration: ${durationUltraSlow}, ${durationSlower}; + transition-delay: ${animations.fastEase}, ${animations.nullEasing}; + } + :host([active])::before { + box-shadow: ${shadow8}; + border-style: solid; + border-color: ${colorBrandBackgroundStatic}; + } + + :host([active][appearance='shadow'])::before { + border-style: none; + border-color: none; + } + + :host([active]:not([appearance='shadow']))::before { + margin: calc(-2 * ${strokeWidthThick}); + border-width: ${strokeWidthThick}; + } + + :host([size='56'][active]:not([appearance='shadow']))::before, + :host([size='64'][active]:not([appearance='shadow']))::before { + margin: calc(-2 * ${strokeWidthThicker}); + border-width: ${strokeWidthThicker}; + } + + :host([size='72'][active]:not([appearance='shadow']))::before, + :host([size='96'][active]:not([appearance='shadow']))::before, + :host([size='120'][active]:not([appearance='shadow']))::before, + :host([size='128'][active]:not([appearance='shadow']))::before { + margin: calc(-2 * ${strokeWidthThickest}); + border-width: ${strokeWidthThickest}; + } + + :host([size='20'][active][appearance])::before, + :host([size='24'][active][appearance])::before, + :host([size='28'][active][appearance])::before { + box-shadow: ${shadow4}; + } + + :host([size='56'][active][appearance])::before, + :host([size='64'][active][appearance])::before { + box-shadow: ${shadow16}; + } + + :host([size='72'][active][appearance])::before, + :host([size='96'][active][appearance])::before, + :host([size='120'][active][appearance])::before, + :host([size='128'][active][appearance])::before { + box-shadow: ${shadow28}; + } + + :host([active][appearance='ring'])::before { + box-shadow: none; + } + + :host([active='inactive']) { + opacity: 0.8; + transform: scale(0.875); + transition-property: transform, opacity; + transition-duration: ${durationUltraSlow}, ${durationFaster}; + transition-delay: ${animations.fastOutSlowInMin}, ${animations.nullEasing}; + } + + :host([active='inactive'])::before { + margin: 0; + opacity: 0; + transition-property: margin, opacity; + transition-duration: ${durationUltraSlow}, ${durationSlower}; + transition-delay: ${animations.fastOutSlowInMin}, ${animations.nullEasing}; + } + + @media screen and (prefers-reduced-motion: reduce) { + :host([active]) { + transition-duration: 0.01ms; + } + + :host([active])::before { + transition-duration: 0.01ms; + transition-delay: 0.01ms; + } + } +`; diff --git a/packages/web-components/src/avatar/avatar.template.ts b/packages/web-components/src/avatar/avatar.template.ts new file mode 100644 index 0000000000000..3e9f595d71405 --- /dev/null +++ b/packages/web-components/src/avatar/avatar.template.ts @@ -0,0 +1,31 @@ +import { ElementViewTemplate, html } from '@microsoft/fast-element'; +import type { Avatar } from './avatar.js'; + +const defaultIconTemplate = html``; + +/** + * The template for the Avatar component. + * @public + */ +export function avatarTemplate(): ElementViewTemplate { + return html` + + `; +} + +export const template: ElementViewTemplate = avatarTemplate(); diff --git a/packages/web-components/src/avatar/avatar.ts b/packages/web-components/src/avatar/avatar.ts new file mode 100644 index 0000000000000..da94ce2626f6e --- /dev/null +++ b/packages/web-components/src/avatar/avatar.ts @@ -0,0 +1,158 @@ +import { attr, FASTElement, nullableNumberConverter } from '@microsoft/fast-element'; +import { getInitials } from '../utils/get-initials.js'; +import { + AvatarActive, + AvatarAppearance, + AvatarColor, + AvatarNamedColor, + AvatarShape, + AvatarSize, +} from './avatar.options.js'; + +/** + * The base class used for constructing a fluent-avatar custom element + * @public + */ +export class Avatar extends FASTElement { + /** + * The name of the person or entity represented by this Avatar. This should always be provided if it is available. + * + * @public + * @remarks + * HTML Attribute: name + */ + @attr + public name?: string | undefined; + + /** + * Provide custom initials rather than one generated via the name + * + * @public + * @remarks + * HTML Attribute: name + */ + @attr + public initials?: string | undefined; + + /** + * Size of the avatar in pixels. + * + * Size is restricted to a limited set of supported values recommended for most uses (see `AvatarSizeValue`) and + * based on design guidelines for the Avatar control. + * + * If a non-supported size is neeeded, set `size` to the next-smaller supported size, and set `width` and `height` + * to override the rendered size. + * + * @public + * @remarks + * HTML Attribute: size + * + */ + @attr({ converter: nullableNumberConverter }) + public size?: AvatarSize | undefined; + + /** + * The avatar can have a circular or square shape. + * + * @public + * @remarks + * HTML Attribute: shape + */ + @attr + public shape?: AvatarShape | undefined; + + /** + * Optional activity indicator + * * active: the avatar will be decorated according to activeAppearance + * * inactive: the avatar will be reduced in size and partially transparent + * * undefined: normal display + * + * @public + * @remarks + * HTML Attribute: active + */ + @attr + public active?: AvatarActive | undefined; + + /** + * The appearance when `active="active"` + * + * @public + * @remarks + * HTML Attribute: appearance + */ + @attr + public appearance?: AvatarAppearance | undefined; + + /** + * The color when displaying either an icon or initials. + * * neutral (default): gray + * * brand: color from the brand palette + * * colorful: picks a color from a set of pre-defined colors, based on a hash of the name (or colorId if provided) + * * [AvatarNamedColor]: a specific color from the theme + * + * @public + * @remarks + * HTML Attribute: color + */ + @attr + public color?: AvatarColor = 'neutral'; + + /** + * Specify a string to be used instead of the name, to determine which color to use when color="colorful". + * Use this when a name is not available, but there is another unique identifier that can be used instead. + */ + @attr({ attribute: 'color-id' }) + public colorId?: AvatarNamedColor | undefined; + + /** + * Sets the data-color attribute used for the visual presentation + * @internal + */ + public generateColor(): AvatarColor | void { + if (!this.color) { + return; + } + + return this.color === AvatarColor.colorful + ? (Avatar.colors[getHashCode(this.colorId ?? this.name ?? '') % Avatar.colors.length] as AvatarColor) + : this.color; + } + + /** + * Generates and sets the initials for the template + * @internal + */ + public generateInitials(): string | void { + if (!this.name && !this.initials) { + return; + } + + // size can be undefined since we default it in CSS only + const size = this.size ?? 32; + + return ( + this.initials ?? + getInitials(this.name, window.getComputedStyle((this as unknown) as HTMLElement).direction === 'rtl', { + firstInitialOnly: size <= 16, + }) + ); + } + + /** + * An array of the available Avatar named colors + */ + public static colors = Object.values(AvatarNamedColor); +} + +// copied from React avatar +const getHashCode = (str: string): number => { + let hashCode = 0; + for (let len: number = str.length - 1; len >= 0; len--) { + const ch = str.charCodeAt(len); + const shift = len % 8; + hashCode ^= (ch << shift) + (ch >> (8 - shift)); // eslint-disable-line no-bitwise + } + + return hashCode; +}; diff --git a/packages/web-components/src/avatar/define.ts b/packages/web-components/src/avatar/define.ts new file mode 100644 index 0000000000000..34933837173dc --- /dev/null +++ b/packages/web-components/src/avatar/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './avatar.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/avatar/index.ts b/packages/web-components/src/avatar/index.ts new file mode 100644 index 0000000000000..8bb35aee4dc2a --- /dev/null +++ b/packages/web-components/src/avatar/index.ts @@ -0,0 +1,5 @@ +export * from './avatar.js'; +export * from './avatar.options.js'; +export { template as AvatarTemplate } from './avatar.template.js'; +export { styles as AvatarStyles } from './avatar.styles.js'; +export { definition as AvatarDefinition } from './avatar.definition.js'; diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index f8394d0a1cf52..041cf1b698364 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -1,5 +1,6 @@ export * from './accordion/index.js'; export * from './accordion-item/index.js'; +export * from './avatar/index.js'; export * from './badge/index.js'; export * from './counter-badge/index.js'; export * from './divider/index.js'; diff --git a/packages/web-components/src/utils/get-initials.ts b/packages/web-components/src/utils/get-initials.ts new file mode 100644 index 0000000000000..7de388f103ec9 --- /dev/null +++ b/packages/web-components/src/utils/get-initials.ts @@ -0,0 +1,110 @@ +/* TODO: This file is a direct copy of the React Avatar utils */ + +/** + * Regular expressions matching characters to ignore when calculating the initials. + */ + +/** + * Regular expression matching characters within various types of enclosures, including the enclosures themselves + * so for example, (xyz) [xyz] {xyz} all would be ignored + */ +const UNWANTED_ENCLOSURES_REGEX: RegExp = /[\(\[\{][^\)\]\}]*[\)\]\}]/g; + +/** + * Regular expression matching special ASCII characters except space, plus some unicode special characters. + * Applies after unwanted enclosures have been removed + */ +// eslint-disable-next-line no-control-regex +const UNWANTED_CHARS_REGEX: RegExp = /[\0-\u001F\!-/:-@\[-`\{-\u00BF\u0250-\u036F\uD800-\uFFFF]/g; + +/** + * Regular expression matching phone numbers. Applied after chars matching UNWANTED_CHARS_REGEX have been removed + * and number has been trimmed for whitespaces + */ +const PHONENUMBER_REGEX: RegExp = /^\d+[\d\s]*(:?ext|x|)\s*\d+$/i; + +/** Regular expression matching one or more spaces. */ +const MULTIPLE_WHITESPACES_REGEX: RegExp = /\s+/g; + +/** + * Regular expression matching languages for which we currently don't support initials. + * Arabic: Arabic, Arabic Supplement, Arabic Extended-A. + * Korean: Hangul Jamo, Hangul Compatibility Jamo, Hangul Jamo Extended-A, Hangul Syllables, Hangul Jamo Extended-B. + * Japanese: Hiragana, Katakana. + * CJK: CJK Unified Ideographs Extension A, CJK Unified Ideographs, CJK Compatibility Ideographs, + * CJK Unified Ideographs Extension B + */ +// eslint-disable-next-line +const UNSUPPORTED_TEXT_REGEX: RegExp = /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\u1100-\u11FF\u3130-\u318F\uA960-\uA97F\uAC00-\uD7AF\uD7B0-\uD7FF\u3040-\u309F\u30A0-\u30FF\u3400-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF]|[\uD840-\uD869][\uDC00-\uDED6]/; + +function getInitialsLatin(displayName: string, isRtl: boolean, firstInitialOnly?: boolean): string { + let initials = ''; + + const splits: string[] = displayName.split(' '); + if (splits.length !== 0) { + initials += splits[0].charAt(0).toUpperCase(); + } + + if (!firstInitialOnly) { + if (splits.length === 2) { + initials += splits[1].charAt(0).toUpperCase(); + } else if (splits.length === 3) { + initials += splits[2].charAt(0).toUpperCase(); + } + } + + if (isRtl && initials.length > 1) { + return initials.charAt(1) + initials.charAt(0); + } + + return initials; +} + +function cleanupDisplayName(displayName: string): string { + displayName = displayName.replace(UNWANTED_ENCLOSURES_REGEX, ''); + displayName = displayName.replace(UNWANTED_CHARS_REGEX, ''); + displayName = displayName.replace(MULTIPLE_WHITESPACES_REGEX, ' '); + displayName = displayName.trim(); + + return displayName; +} + +/** + * Get (up to 2 characters) initials based on display name of the persona. + * + * @param displayName - The full name of the person or entity + * @param isRtl - Whether the display is in RTL + * @param options - Extra options to control the behavior of getInitials + * + * @returns The 1 or 2 character initials based on the name. Or an empty string if no initials + * could be derived from the name. + * + * @internal + */ +export function getInitials( + displayName: string | undefined | null, + isRtl: boolean, + options?: { + /** Should initials be generated from phone numbers (default false) */ + allowPhoneInitials?: boolean; + + /** Returns only the first initial */ + firstInitialOnly?: boolean; + }, +): string { + if (!displayName) { + return ''; + } + + displayName = cleanupDisplayName(displayName); + + // For names containing CJK characters, and phone numbers, we don't display initials + if ( + UNSUPPORTED_TEXT_REGEX.test(displayName) || + (!options?.allowPhoneInitials && PHONENUMBER_REGEX.test(displayName)) + ) { + return ''; + } + + return getInitialsLatin(displayName, isRtl, options?.firstInitialOnly); +} From 7a06f79f8c1e7f2ccd1b54d4a6c485f1e716247b Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Mon, 27 Feb 2023 04:27:11 +0000 Subject: [PATCH 043/203] applying package updates --- ...-1c73e6e8-61a0-46c8-b69e-0820f5a2488d.json | 7 ----- ...-2500a738-206b-4f66-b5d5-c60924e40a5b.json | 7 ----- ...-a862230b-9028-4c6a-8a43-3be819a6128e.json | 7 ----- packages/web-components/CHANGELOG.json | 27 +++++++++++++++++++ packages/web-components/CHANGELOG.md | 13 ++++++++- packages/web-components/package.json | 2 +- 6 files changed, 40 insertions(+), 23 deletions(-) delete mode 100644 change/@fluentui-web-components-1c73e6e8-61a0-46c8-b69e-0820f5a2488d.json delete mode 100644 change/@fluentui-web-components-2500a738-206b-4f66-b5d5-c60924e40a5b.json delete mode 100644 change/@fluentui-web-components-a862230b-9028-4c6a-8a43-3be819a6128e.json diff --git a/change/@fluentui-web-components-1c73e6e8-61a0-46c8-b69e-0820f5a2488d.json b/change/@fluentui-web-components-1c73e6e8-61a0-46c8-b69e-0820f5a2488d.json deleted file mode 100644 index ab3341afdf7ad..0000000000000 --- a/change/@fluentui-web-components-1c73e6e8-61a0-46c8-b69e-0820f5a2488d.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat(avatar): add Avatar web component", - "packageName": "@fluentui/web-components", - "email": "chhol@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-2500a738-206b-4f66-b5d5-c60924e40a5b.json b/change/@fluentui-web-components-2500a738-206b-4f66-b5d5-c60924e40a5b.json deleted file mode 100644 index 21d5f30077f2d..0000000000000 --- a/change/@fluentui-web-components-2500a738-206b-4f66-b5d5-c60924e40a5b.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat(divider): Add divider web component", - "packageName": "@fluentui/web-components", - "email": "harankin@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-a862230b-9028-4c6a-8a43-3be819a6128e.json b/change/@fluentui-web-components-a862230b-9028-4c6a-8a43-3be819a6128e.json deleted file mode 100644 index 5dc002fd61244..0000000000000 --- a/change/@fluentui-web-components-a862230b-9028-4c6a-8a43-3be819a6128e.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat(image): Add image web component", - "packageName": "@fluentui/web-components", - "email": "harankin@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index fed39f77b5577..39242fb14a3e6 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,33 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Mon, 27 Feb 2023 04:27:02 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.7", + "version": "3.0.0-alpha.7", + "comments": { + "prerelease": [ + { + "author": "chhol@microsoft.com", + "package": "@fluentui/web-components", + "commit": "4309a0d5afbe56dab0b1204922a37873fe832c8b", + "comment": "feat(avatar): add Avatar web component" + }, + { + "author": "harankin@microsoft.com", + "package": "@fluentui/web-components", + "commit": "7d9573d73b4be010c2b07540fa0c23c27aba2821", + "comment": "feat(divider): Add divider web component" + }, + { + "author": "harankin@microsoft.com", + "package": "@fluentui/web-components", + "commit": "e793ad8a7f7ae0239a808439d121cf012dd414e5", + "comment": "feat(image): Add image web component" + } + ] + } + }, { "date": "Fri, 24 Feb 2023 04:20:32 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.6", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index 0866f5a0ac53f..69bc5d05608c3 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,20 @@ # Change Log - @fluentui/web-components -This log was last generated on Fri, 24 Feb 2023 04:20:32 GMT and should not be manually modified. +This log was last generated on Mon, 27 Feb 2023 04:27:02 GMT and should not be manually modified. +## [3.0.0-alpha.7](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.7) + +Mon, 27 Feb 2023 04:27:02 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.6..@fluentui/web-components_v3.0.0-alpha.7) + +### Changes + +- feat(avatar): add Avatar web component ([PR #26729](https://github.com/microsoft/fluentui/pull/26729) by chhol@microsoft.com) +- feat(divider): Add divider web component ([PR #26901](https://github.com/microsoft/fluentui/pull/26901) by harankin@microsoft.com) +- feat(image): Add image web component ([PR #26936](https://github.com/microsoft/fluentui/pull/26936) by harankin@microsoft.com) + ## [3.0.0-alpha.6](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.6) Fri, 24 Feb 2023 04:20:32 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 7093c1856539d..3759989b9e6f9 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.6", + "version": "3.0.0-alpha.7", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From e6e1b2b273471a55caec83e889a2fc69fd93f287 Mon Sep 17 00:00:00 2001 From: Miroslav Stastny Date: Mon, 27 Feb 2023 13:28:09 +0100 Subject: [PATCH 044/203] chore: Enable Typescript strict mode (#26950) * chore: Enable Typescript strict mode * change file * revert unnecessary change * update api-report after rebase --- ...-b348c686-1571-481e-9410-634431e842c9.json | 7 +++ packages/web-components/docs/api-report.md | 47 ++++++++++++------- .../src/accordion-item/accordion-item.ts | 4 +- packages/web-components/src/badge/badge.ts | 4 +- .../counter-badge/counter-badge.template.ts | 7 +-- .../src/counter-badge/counter-badge.ts | 8 ++-- .../src/progress-bar/progress-bar.ts | 6 +-- .../web-components/src/spinner/spinner.ts | 4 +- packages/web-components/src/text/text.ts | 8 ++-- .../web-components/src/theme/design-tokens.ts | 5 ++ .../web-components/src/theme/set-theme.ts | 4 +- tsconfig.base.wc.json | 2 +- 12 files changed, 67 insertions(+), 39 deletions(-) create mode 100644 change/@fluentui-web-components-b348c686-1571-481e-9410-634431e842c9.json diff --git a/change/@fluentui-web-components-b348c686-1571-481e-9410-634431e842c9.json b/change/@fluentui-web-components-b348c686-1571-481e-9410-634431e842c9.json new file mode 100644 index 0000000000000..cdc6f2e7925bc --- /dev/null +++ b/change/@fluentui-web-components-b348c686-1571-481e-9410-634431e842c9.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: Enable Typescript strict mode", + "packageName": "@fluentui/web-components", + "email": "miroslav.stastny@microsoft.com", + "dependentChangeType": "none" +} diff --git a/packages/web-components/docs/api-report.md b/packages/web-components/docs/api-report.md index 2e81845851dce..98b44517c142a 100644 --- a/packages/web-components/docs/api-report.md +++ b/packages/web-components/docs/api-report.md @@ -37,9 +37,9 @@ export class AccordionItem extends FASTAccordionItem { // @public block: boolean; // @public - expandIconPosition: AccordionItemExpandIconPosition; + expandIconPosition?: AccordionItemExpandIconPosition; // @public - size: AccordionItemSize; + size?: AccordionItemSize; } // Warning: (ae-incompatible-release-tags) The symbol "definition" is marked as @public, but its signature references "AccordionItem" which is marked as @internal @@ -239,8 +239,8 @@ export const AvatarTemplate: ElementViewTemplate; export class Badge extends FASTElement { appearance: BadgeAppearance; color: BadgeColor; - shape: BadgeShape; - size: BadgeSize; + shape?: BadgeShape; + size?: BadgeSize; } // @internal @@ -648,9 +648,15 @@ export const colorNeutralShadowKeyLighter: CSSDesignToken; // @public (undocumented) export const colorNeutralStencil1: CSSDesignToken; +// @public (undocumented) +export const colorNeutralStencil1Alpha: CSSDesignToken; + // @public (undocumented) export const colorNeutralStencil2: CSSDesignToken; +// @public (undocumented) +export const colorNeutralStencil2Alpha: CSSDesignToken; + // @public (undocumented) export const colorNeutralStroke1: CSSDesignToken; @@ -891,6 +897,9 @@ export const colorPaletteGreenForeground2: CSSDesignToken; // @public (undocumented) export const colorPaletteGreenForeground3: CSSDesignToken; +// @public (undocumented) +export const colorPaletteGreenForegroundInverted: CSSDesignToken; + // @public (undocumented) export const colorPaletteLavenderBackground2: CSSDesignToken; @@ -1080,6 +1089,9 @@ export const colorPaletteRedForeground2: CSSDesignToken; // @public (undocumented) export const colorPaletteRedForeground3: CSSDesignToken; +// @public (undocumented) +export const colorPaletteRedForegroundInverted: CSSDesignToken; + // @public (undocumented) export const colorPaletteRoyalBlueBackground2: CSSDesignToken; @@ -1143,6 +1155,9 @@ export const colorPaletteYellowForeground2: CSSDesignToken; // @public (undocumented) export const colorPaletteYellowForeground3: CSSDesignToken; +// @public (undocumented) +export const colorPaletteYellowForegroundInverted: CSSDesignToken; + // @public (undocumented) export const colorScrollbarOverlay: CSSDesignToken; @@ -1210,8 +1225,8 @@ export const colorTransparentStrokeInteractive: CSSDesignToken; // // @public export class CounterBadge extends FASTElement { - appearance: CounterBadgeAppearance; - color: CounterBadgeColor; + appearance?: CounterBadgeAppearance; + color?: CounterBadgeColor; count: number; // (undocumented) protected countChanged(): void; @@ -1221,9 +1236,9 @@ export class CounterBadge extends FASTElement { protected overflowCountChanged(): void; // @internal setCount(): string | void; - shape: CounterBadgeShape; + shape?: CounterBadgeShape; showZero: boolean; - size: CounterBadgeSize; + size?: CounterBadgeSize; } // @internal @@ -1506,8 +1521,8 @@ export const lineHeightHero900: CSSDesignToken; // @public class ProgressBar_2 extends FASTProgress { - shape: ProgressBarShape; - thickness: ProgressBarThickness; + shape?: ProgressBarShape; + thickness?: ProgressBarThickness; validationState: ProgressBarValidationState | null; } export { ProgressBar_2 as ProgressBar } @@ -1656,8 +1671,8 @@ export const spacingVerticalXXXL: CSSDesignToken; // @public export class Spinner extends FASTProgressRing { - appearance: SpinnerAppearance; - size: SpinnerSize; + appearance?: SpinnerAppearance; + size?: SpinnerSize; } // @public @@ -1727,16 +1742,16 @@ export const switchTemplate: ElementViewTemplate; // @public class Text_2 extends FASTElement { - align: TextAlign; + align?: TextAlign; block: boolean; - font: TextFont; + font?: TextFont; italic: boolean; nowrap: boolean; - size: TextSize; + size?: TextSize; strikethrough: boolean; truncate: boolean; underline: boolean; - weight: TextWeight; + weight?: TextWeight; } export { Text_2 as Text } diff --git a/packages/web-components/src/accordion-item/accordion-item.ts b/packages/web-components/src/accordion-item/accordion-item.ts index 0e3411cc40ae9..95c25a1435f41 100644 --- a/packages/web-components/src/accordion-item/accordion-item.ts +++ b/packages/web-components/src/accordion-item/accordion-item.ts @@ -15,7 +15,7 @@ export class AccordionItem extends FASTAccordionItem { * HTML Attribute: size */ @attr - public size: AccordionItemSize; + public size?: AccordionItemSize; /** * Sets the width of the focus state. @@ -36,5 +36,5 @@ export class AccordionItem extends FASTAccordionItem { * HTML Attribute: expandIconPosition */ @attr({ attribute: 'expand-icon-position' }) - public expandIconPosition: AccordionItemExpandIconPosition; + public expandIconPosition?: AccordionItemExpandIconPosition; } diff --git a/packages/web-components/src/badge/badge.ts b/packages/web-components/src/badge/badge.ts index 25481e08d57a5..ab0366a84d021 100644 --- a/packages/web-components/src/badge/badge.ts +++ b/packages/web-components/src/badge/badge.ts @@ -34,7 +34,7 @@ export class Badge extends FASTElement { * HTML Attribute: shape */ @attr - public shape: BadgeShape; + public shape?: BadgeShape; /** * The size the badge should have. @@ -44,7 +44,7 @@ export class Badge extends FASTElement { * HTML Attribute: size */ @attr - public size: BadgeSize; + public size?: BadgeSize; } /** diff --git a/packages/web-components/src/counter-badge/counter-badge.template.ts b/packages/web-components/src/counter-badge/counter-badge.template.ts index f0049a3abc528..338fab4220c0b 100644 --- a/packages/web-components/src/counter-badge/counter-badge.template.ts +++ b/packages/web-components/src/counter-badge/counter-badge.template.ts @@ -1,10 +1,11 @@ import { ElementViewTemplate, html } from '@microsoft/fast-element'; import { badgeTemplate } from '../badge/badge.template.js'; +import { Badge } from '../badge/badge.js'; import { CounterBadge } from './counter-badge.js'; import { CounterBadgeOptions } from './counter-badge.options.js'; -function composeTemplate(options: CounterBadgeOptions = {}): ElementViewTemplate { - return badgeTemplate({ +function composeTemplate(options: CounterBadgeOptions = {}): ElementViewTemplate { + return badgeTemplate({ defaultContent: html`${x => x.setCount()}`, }); } @@ -13,4 +14,4 @@ function composeTemplate(options: CounterBadgeOptions = * The template for the Counter Badge component. * @public */ -export const template: ElementViewTemplate = composeTemplate(); +export const template: ElementViewTemplate = composeTemplate(); diff --git a/packages/web-components/src/counter-badge/counter-badge.ts b/packages/web-components/src/counter-badge/counter-badge.ts index 38ca98713df4b..0794b2f9d853d 100644 --- a/packages/web-components/src/counter-badge/counter-badge.ts +++ b/packages/web-components/src/counter-badge/counter-badge.ts @@ -20,7 +20,7 @@ export class CounterBadge extends FASTElement { * HTML Attribute: appearance */ @attr - public appearance: CounterBadgeAppearance; + public appearance?: CounterBadgeAppearance; /** * The color the badge should have. @@ -30,7 +30,7 @@ export class CounterBadge extends FASTElement { * HTML Attribute: color */ @attr - public color: CounterBadgeColor; + public color?: CounterBadgeColor; /** * The shape the badge should have. * @@ -39,7 +39,7 @@ export class CounterBadge extends FASTElement { * HTML Attribute: shape */ @attr - public shape: CounterBadgeShape; + public shape?: CounterBadgeShape; /** * The size the badge should have. @@ -49,7 +49,7 @@ export class CounterBadge extends FASTElement { * HTML Attribute: size */ @attr - public size: CounterBadgeSize; + public size?: CounterBadgeSize; /** * The count the badge should have. diff --git a/packages/web-components/src/progress-bar/progress-bar.ts b/packages/web-components/src/progress-bar/progress-bar.ts index aff1a3e153638..7fdd92ee869d2 100644 --- a/packages/web-components/src/progress-bar/progress-bar.ts +++ b/packages/web-components/src/progress-bar/progress-bar.ts @@ -15,7 +15,7 @@ export class ProgressBar extends FASTProgress { * HTML Attribute: thickness */ @attr - public thickness: ProgressBarThickness; + public thickness?: ProgressBarThickness; /** * The shape of the progress bar @@ -24,7 +24,7 @@ export class ProgressBar extends FASTProgress { * HTML Attribute: shape */ @attr - public shape: ProgressBarShape; + public shape?: ProgressBarShape; /** * The validation state of the progress bar @@ -33,5 +33,5 @@ export class ProgressBar extends FASTProgress { * HTML Attribute: validation-state */ @attr({ attribute: 'validation-state' }) - public validationState: ProgressBarValidationState | null; + public validationState: ProgressBarValidationState | null = null; } diff --git a/packages/web-components/src/spinner/spinner.ts b/packages/web-components/src/spinner/spinner.ts index 75a70af5f8949..e1b1b4c925b9f 100644 --- a/packages/web-components/src/spinner/spinner.ts +++ b/packages/web-components/src/spinner/spinner.ts @@ -16,7 +16,7 @@ export class Spinner extends FASTProgressRing { * HTML Attribute: size */ @attr - public size: SpinnerSize; + public size?: SpinnerSize; /** * The appearance of the spinner @@ -26,5 +26,5 @@ export class Spinner extends FASTProgressRing { * HTML Attribute: appearance */ @attr - public appearance: SpinnerAppearance; + public appearance?: SpinnerAppearance; } diff --git a/packages/web-components/src/text/text.ts b/packages/web-components/src/text/text.ts index a666fb0950822..c0cd166a45557 100644 --- a/packages/web-components/src/text/text.ts +++ b/packages/web-components/src/text/text.ts @@ -77,7 +77,7 @@ export class Text extends FASTElement { * */ @attr - size: TextSize; + size?: TextSize; /** * THe Text font @@ -87,7 +87,7 @@ export class Text extends FASTElement { * HTML Attribute: font */ @attr - font: TextFont; + font?: TextFont; /** * THe Text weight @@ -97,7 +97,7 @@ export class Text extends FASTElement { * HTML Attribute: weight */ @attr - weight: TextWeight; + weight?: TextWeight; /** * THe Text align @@ -107,5 +107,5 @@ export class Text extends FASTElement { * HTML Attribute: align */ @attr - align: TextAlign; + align?: TextAlign; } diff --git a/packages/web-components/src/theme/design-tokens.ts b/packages/web-components/src/theme/design-tokens.ts index aaed69106d57f..98e4c5fafd305 100644 --- a/packages/web-components/src/theme/design-tokens.ts +++ b/packages/web-components/src/theme/design-tokens.ts @@ -172,6 +172,8 @@ export const colorNeutralBackgroundDisabled = create('colorNeutralBackgr export const colorNeutralBackgroundInvertedDisabled = create('colorNeutralBackgroundInvertedDisabled'); export const colorNeutralStencil1 = create('colorNeutralStencil1'); export const colorNeutralStencil2 = create('colorNeutralStencil2'); +export const colorNeutralStencil1Alpha = create('colorNeutralStencil1Alpha'); +export const colorNeutralStencil2Alpha = create('colorNeutralStencil2Alpha'); export const colorBackgroundOverlay = create('colorBackgroundOverlay'); export const colorScrollbarOverlay = create('colorScrollbarOverlay'); export const colorBrandBackground = create('colorBrandBackground'); @@ -369,6 +371,9 @@ export const colorPalettePlatinumBorderActive = create('colorPalettePlat export const colorPaletteAnchorBackground2 = create('colorPaletteAnchorBackground2'); export const colorPaletteAnchorForeground2 = create('colorPaletteAnchorForeground2'); export const colorPaletteAnchorBorderActive = create('colorPaletteAnchorBorderActive'); +export const colorPaletteRedForegroundInverted = create('colorPaletteRedForegroundInverted'); +export const colorPaletteGreenForegroundInverted = create('colorPaletteGreenForegroundInverted'); +export const colorPaletteYellowForegroundInverted = create('colorPaletteYellowForegroundInverted'); export const shadow2 = create('shadow2'); export const shadow4 = create('shadow4'); export const shadow8 = create('shadow8'); diff --git a/packages/web-components/src/theme/set-theme.ts b/packages/web-components/src/theme/set-theme.ts index ea0aa8cd11065..06529c40de216 100644 --- a/packages/web-components/src/theme/set-theme.ts +++ b/packages/web-components/src/theme/set-theme.ts @@ -1,7 +1,7 @@ import type { Theme } from '@fluentui/tokens'; import * as tokens from './design-tokens.js'; -const tokenNames = Object.keys(tokens); +const tokenNames = Object.keys(tokens) as (keyof Theme)[]; /** * Sets the theme tokens on defaultNode. @@ -9,6 +9,6 @@ const tokenNames = Object.keys(tokens); */ export const setTheme = (theme: Theme) => { for (const t of tokenNames) { - tokens[t].withDefault(theme[t]); + tokens[t].withDefault(theme[t] as string); } }; diff --git a/tsconfig.base.wc.json b/tsconfig.base.wc.json index e209b3fa7f7f6..90ce34646525c 100644 --- a/tsconfig.base.wc.json +++ b/tsconfig.base.wc.json @@ -5,7 +5,7 @@ "moduleResolution": "Node16", "esModuleInterop": true, "sourceMap": true, - "strictNullChecks": true, + "strict": true, "forceConsistentCasingInFileNames": true, "skipLibCheck": true, "pretty": true, From 6c949a07dc4012cc37e387c896e64b0e65390d60 Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Mon, 27 Feb 2023 15:07:20 -0800 Subject: [PATCH 045/203] divides accordion and accordion item readme (#26938) * divides accordion and accordion item readme * updates accordion docs * updates accordion docs * formats docs table * yarn change --- ...-3cce950f-a483-4620-ba7b-696cc922f331.json | 7 + .../src/accordion-item/README.md | 141 ++++++++++++++++++ .../web-components/src/accordion/README.md | 106 ++----------- 3 files changed, 162 insertions(+), 92 deletions(-) create mode 100644 change/@fluentui-web-components-3cce950f-a483-4620-ba7b-696cc922f331.json create mode 100644 packages/web-components/src/accordion-item/README.md diff --git a/change/@fluentui-web-components-3cce950f-a483-4620-ba7b-696cc922f331.json b/change/@fluentui-web-components-3cce950f-a483-4620-ba7b-696cc922f331.json new file mode 100644 index 0000000000000..4f45a98bfd980 --- /dev/null +++ b/change/@fluentui-web-components-3cce950f-a483-4620-ba7b-696cc922f331.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "updates wc3 accordion and accordion item docs", + "packageName": "@fluentui/web-components", + "email": "brianbrady@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/src/accordion-item/README.md b/packages/web-components/src/accordion-item/README.md new file mode 100644 index 0000000000000..946769567defe --- /dev/null +++ b/packages/web-components/src/accordion-item/README.md @@ -0,0 +1,141 @@ +# Accordion Item + +As defined by the [W3C](https://w3c.github.io/aria-practices/#accordion): + +> An accordion is a vertically stacked set of interactive headings that each contain a title, content snippet, or thumbnail representing a section of content. The headings function as controls that enable users to reveal or hide their associated sections of content. Accordions are commonly used to reduce the need to scroll when presenting multiple sections of content on a single page. + +
+ +## **Design Spec** + +[Link to Accordion Item Design Spec in Figma](https://www.figma.com/file/7X3Tgd3fTurii3FACrfhzo/Accordion?node-id=2777%3A42482&t=jHgc4PXRMQH6rPmy-0) + +
+ +## **Engineering Spec** + +Fluent WC3 Accordion Item extends from the [FAST Accordion Item](https://explore.fast.design/components/fast-accordion-item) and is intended to be as close to the Fluent UI React 9 Accordion implementation as possible. However, due to the nature of web components there will not be 100% parity between the two. + +
+ +## Class: `AccordionItem` + +
+ +### **Component Name** + +`AccordionItem` + +
+ +### **Variables** + +| Name | Description | Type | +| --------------------------------- | -------------------------- | --------------------------------------------------------------------------------- | +| `AccordionItemSize` | Expand modes for Accordion | `{ small: "small", medium: "medium", large: "large", extraLarge: "extra-large" }` | +| `AccordionItemExpandIconPosition` | Expand icon position | `{ start: "start", end: "end" }` | + +
+ +### **Fields** + +| Name | Privacy | Type | Default | Description | Inherited From | +| -------------------- | ------- | --------------------------------- | -------- | ---------------------------------------------------------------------------------------------- | -------------- | +| `headinglevel` | public | `1 or 2 or 3 or 4 or 5 or 6` | `2` | Configures the [level](https://www.w3.org/TR/wai-aria-1.1/#aria-level) of the heading element. | | +| `expanded` | public | `boolean` | `false` | Expands or collapses the item. | | +| `disabled` | public | `boolean` | `false` | Disables an accordion item | | +| `id` | public | `string` | | The item ID | | +| `size` | public | `AccordionItemSize` | `medium` | The font size of the AccordionItem header. | +| `block` | public | `boolean` | `true` | Sets the width of the focus state. | +| `expandIconPosition` | public | `AccordionItemExpandIconPosition` | `start` | Sets the position of the expand icon | + +
+ +### **Events** + +| Name | Type | Description | Inherited From | +| -------- | ---- | -------------------------------------------------------- | -------------- | +| `change` | | Fires a custom 'change' event when the button is invoked | | + +
+ +### **Attributes** + +| Name | Field | +| -------------------- | ------------------ | +| `heading-level` | headinglevel | +| | expanded | +| | disabled | +| | block | +| `id` | id | +| `expandIconPosition` | expandIconPosition | +| `size` | size | + +
+ +### **Slots** + +| Name | Description | +| ---------------- | -------------------------------------------------------------------------------- | +| `start` | The slot used for a presentation icon when expanded | +| `end` | The slot used for a presentation icon when collapsed | +| `heading` | Content which serves as the accordion item heading and text of the expand button | +| | The default slot for accordion item content | +| `expanded-icon` | The slot used for a custom expanded icon | +| `collapsed-icon` | The slot used for a custom collapsed icon | + +
+
+
+ +## **Accessibility** + +[W3 Accordion Item Spec](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/) + +
+ +### **WAI-ARIA Roles, States, and Properties** + +- `role = "button"` + - The title of each accordion header is contained in an element with role button. +- `role = "heading"` + - Each accordion header button is wrapped in an element with role heading that has a value set for aria-level that is appropriate for the information architecture of the page. +- `aria-expanded` + - If the accordion panel associated with an accordion header is visible, the header button element has aria-expanded set to true. If the panel is not visible, aria-expanded is set to false. +- `aria-controls` + - The accordion header button element has aria-controls set to the ID of the element containing the accordion panel content. +- `aria-disabled` + - If the accordion panel associated with an accordion header is visible, and if the accordion does not permit the panel to be collapsed, the header button element has aria-disabled set to true. + +
+
+
+ +## **Preparation** + +
+ +### **Fluent Web Component v3 v.s Fluent React 9** + +
+ +**Component and Slot Mapping** + +| Fluent UI React 9 | Fluent Web Components 3 | +| ------------------- | ------------------------- | +| `` | `` | +| `` | `named slot = "heading"` | +| `` | `default slotted content` | + +
+ +**Property Mapping** +| Fluent UI React 9 | Fluent Web Components 3 | Description of difference | +| ------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------- | +| `defaultOpenItems: number`| `expand: boolean` | `defaultOpenItems` is a number property set on the `Accordion` corresponding to the intended `AccordionItem` to be expanded.
`expand` is a boolean property set directly on the `AccordionItem` intended to be expanded. | +| `size` | `size` | | +| `as: 'h1'` | `'h2'` | `'h3'` | `'h4'` | `'h5'` | `'h6'` | `headinglevel: 1` | `2` | `3` | `4` | `5` | `6` | `as` property sets a wrapper around the `AccordionItem` header with the corresponding header tag ( `h1`, `h2`, etc. )
`headinglevel` sets the `aria-level` attribute to the corresponding heading level. +| `disabled` | `disabled` | +| `expandIconPosition` | `expand-icon-position` | +| `expandIcon` | `named slot: collapsed-icon` + `expanded-icon` | `expandIcon` is a prop that is passed a ternary to render the appropriate icon.
`collapsed-icon` and `expanded-icon` are named slots to supply the appropriate icons. +| `icon` | `named slot: start` + `end` | `icon` is a property set on the `AccordionHeader` through which an icon is passed
`start` and `end` are named slots through which to supply a presentation icon. diff --git a/packages/web-components/src/accordion/README.md b/packages/web-components/src/accordion/README.md index 7756994649bb7..54992e92207fa 100644 --- a/packages/web-components/src/accordion/README.md +++ b/packages/web-components/src/accordion/README.md @@ -1,4 +1,4 @@ -# Accordion + Accordion Item +# Accordion As defined by the [W3C](https://w3c.github.io/aria-practices/#accordion): @@ -14,7 +14,7 @@ As defined by the [W3C](https://w3c.github.io/aria-practices/#accordion): ## **Engineering Spec** -Fluent WC3 Accordion extends from the FAST Accordion [FAST Accordion](https://explore.fast.design/components/fast-accordion) and is intended to be as close to the Fluent UI React 9 Menu implementation as possible. However, due to the nature of web components there will not be 100% parity between the two. +Fluent WC3 Accordion extends from the [FAST Accordion](https://explore.fast.design/components/fast-accordion) and is intended to be as close to the Fluent UI React 9 Accordion implementation as possible. However, due to the nature of web components there will not be 100% parity between the two.
@@ -22,6 +22,12 @@ Fluent WC3 Accordion extends from the FAST Accordion [FAST Accordion](https://ex
+### **Component Name** + +`Accordion` + +
+ ### **Variables** | Name | Description | Type | @@ -67,70 +73,6 @@ Fluent WC3 Accordion extends from the FAST Accordion [FAST Accordion](https://ex
-## Class: `AccordionItem` - -
- -### **Variables** - -| Name | Description | Type | -| --------------------------------- | -------------------------- | --------------------------------------------------------------------------------- | -| `AccordionItemSize` | Expand modes for Accordion | `{ small: "small", medium: "medium", large: "large", extraLarge: "extra-large" }` | -| `AccordionItemExpandIconPosition` | Expand icon position | `{ start: "start", end: "end" }` | - -
- -### **Fields** - -| Name | Privacy | Type | Default | Description | Inherited From | -| -------------------- | ------- | --------------------------------- | -------- | ---------------------------------------------------------------------------------------------- | -------------- | -| `headinglevel` | public | `1 or 2 or 3 or 4 or 5 or 6` | `2` | Configures the [level](https://www.w3.org/TR/wai-aria-1.1/#aria-level) of the heading element. | | -| `expanded` | public | `boolean` | `false` | Expands or collapses the item. | | -| `disabled` | public | `boolean` | `false` | Disables an accordion item | | -| `id` | public | `string` | | The item ID | | -| `size` | public | `AccordionItemSize` | `medium` | The font size of the AccordionItem header. | -| `block` | public | `boolean` | `true` | Sets the width of the focus state. | -| `expandIconPosition` | public | `AccordionItemExpandIconPosition` | `start` | Sets the position of the expand icon | - -
- -### **Events** - -| Name | Type | Description | Inherited From | -| -------- | ---- | -------------------------------------------------------- | -------------- | -| `change` | | Fires a custom 'change' event when the button is invoked | | - -
- -### **Attributes** - -| Name | Field | -| -------------------- | ------------------ | -| `heading-level` | headinglevel | -| | expanded | -| | disabled | -| | block | -| `id` | id | -| `expandIconPosition` | expandIconPosition | -| `size` | size | - -
- -### **Slots** - -| Name | Description | -| ---------------- | -------------------------------------------------------------------------------- | -| `start` | The slot used for a presentation icon when expanded | -| `end` | The slot used for a presentation icon when collapsed | -| `heading` | Content which serves as the accordion item heading and text of the expand button | -| | The default slot for accordion item content | -| `expanded-icon` | The slot used for a custom expanded icon | -| `collapsed-icon` | The slot used for a custom collapsed icon | - -
-
-
- ## **Accessibility** [W3 Accordion Spec](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/) @@ -139,17 +81,6 @@ Fluent WC3 Accordion extends from the FAST Accordion [FAST Accordion](https://ex ### **WAI-ARIA Roles, States, and Properties** -- `role = "button"` - - The title of each accordion header is contained in an element with role button. -- `role = "heading"` - - Each accordion header button is wrapped in an element with role heading that has a value set for aria-level that is appropriate for the information architecture of the page. -- `aria-expanded` - - If the accordion panel associated with an accordion header is visible, the header button element has aria-expanded set to true. If the panel is not visible, aria-expanded is set to false. -- `aria-controls` - - The accordion header button element has aria-controls set to the ID of the element containing the accordion panel content. -- `aria-disabled` - - If the accordion panel associated with an accordion header is visible, and if the accordion does not permit the panel to be collapsed, the header button element has aria-disabled set to true. -


@@ -164,23 +95,14 @@ Fluent WC3 Accordion extends from the FAST Accordion [FAST Accordion](https://ex **Component and Slot Mapping** -| Fluent UI React 9 | Fluent Web Components 3 | -| ------------------- | ------------------------- | -| `` | `` | -| `` | `` | -| `` | `named slot = "heading"` | -| `` | `default slotted content` | +| Fluent UI React 9 | Fluent Web Components 3 | +| ----------------- | ----------------------- | +| `` | `` |
**Property Mapping** | Fluent UI React 9 | Fluent Web Components 3 | Description of difference | -|---------------------------|---------------------------|------------------------------------------------------------------------------------------| -| `defaultOpenItems: number`| `expand: boolean` | _FuiR9_ `defaultOpenItems` is a number property set on the `Accordion` corresponding to the intended `AccordionItem` to be expanded.
`expand` is a boolean property set directly on the `AccordionItem` intended to be expanded. -| `multiple: boolean` | `expandmode: "single"` | `"multiple"`| | -| `size` | `size` | -| `as: 'h1'` | `'h2'` | `'h3'` | `'h4'` | `'h5'` | `'h6'` | `headinglevel: 1` | `2` | `3` | `4` | `5` | `6` | `as` property sets a wrapper around the `AccordionItem` header with the corresponding header tag ( `h1`, `h2`, etc. )
`headinglevel` sets the `aria-level` attribute to the corresponding heading level. -| `disabled` | `disabled` | -| `expandIconPosition` | `expandIconPosition` | -| `expandIcon` | `named slot: collapsed-icon` + `expanded-icon` | `expandIcon` is a prop that is passed a ternary to render the appropriate icon.
`collapsed-icon` and `expanded-icon` are named slots to supply the appropriate icons. -| `icon` | `named slot: start` + `end` | `icon` is a property set on the `AccordionHeader` through which an icon is passed
`start` and `end` are named slots through which to supply a presentation icon. +| ------------------------- | ------------------------------------------ |---------------------------------------------------------- | +| `defaultOpenItems: number`| `expand: boolean` | `defaultOpenItems` is a number property set on the `Accordion` corresponding to the intended `AccordionItem` to be expanded.
`expand` is a boolean property set directly on the `AccordionItem` intended to be expanded | +| `multiple: boolean` | `expand-mode: "single" \| "multiple"` | | From beddd9c14ef70bc48a63f3d8d978f722c3c2cfe4 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Tue, 28 Feb 2023 04:25:22 +0000 Subject: [PATCH 046/203] applying package updates --- ...-3cce950f-a483-4620-ba7b-696cc922f331.json | 7 ------ ...-b348c686-1571-481e-9410-634431e842c9.json | 7 ------ packages/web-components/CHANGELOG.json | 23 +++++++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++- packages/web-components/package.json | 2 +- 5 files changed, 34 insertions(+), 16 deletions(-) delete mode 100644 change/@fluentui-web-components-3cce950f-a483-4620-ba7b-696cc922f331.json delete mode 100644 change/@fluentui-web-components-b348c686-1571-481e-9410-634431e842c9.json diff --git a/change/@fluentui-web-components-3cce950f-a483-4620-ba7b-696cc922f331.json b/change/@fluentui-web-components-3cce950f-a483-4620-ba7b-696cc922f331.json deleted file mode 100644 index 4f45a98bfd980..0000000000000 --- a/change/@fluentui-web-components-3cce950f-a483-4620-ba7b-696cc922f331.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "updates wc3 accordion and accordion item docs", - "packageName": "@fluentui/web-components", - "email": "brianbrady@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-b348c686-1571-481e-9410-634431e842c9.json b/change/@fluentui-web-components-b348c686-1571-481e-9410-634431e842c9.json deleted file mode 100644 index cdc6f2e7925bc..0000000000000 --- a/change/@fluentui-web-components-b348c686-1571-481e-9410-634431e842c9.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "chore: Enable Typescript strict mode", - "packageName": "@fluentui/web-components", - "email": "miroslav.stastny@microsoft.com", - "dependentChangeType": "none" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 39242fb14a3e6..8e683dc66791d 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,29 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Tue, 28 Feb 2023 04:25:15 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.8", + "version": "3.0.0-alpha.8", + "comments": { + "prerelease": [ + { + "author": "brianbrady@microsoft.com", + "package": "@fluentui/web-components", + "commit": "c0d4b0def168396e9139672146bbadbe408ea4d4", + "comment": "updates wc3 accordion and accordion item docs" + } + ], + "none": [ + { + "author": "miroslav.stastny@microsoft.com", + "package": "@fluentui/web-components", + "commit": "237267b5ad816d090011c93f2922476c1abfe87f", + "comment": "chore: Enable Typescript strict mode" + } + ] + } + }, { "date": "Mon, 27 Feb 2023 04:27:02 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.7", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index 69bc5d05608c3..c679c5a84be53 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Mon, 27 Feb 2023 04:27:02 GMT and should not be manually modified. +This log was last generated on Tue, 28 Feb 2023 04:25:15 GMT and should not be manually modified. +## [3.0.0-alpha.8](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.8) + +Tue, 28 Feb 2023 04:25:15 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.7..@fluentui/web-components_v3.0.0-alpha.8) + +### Changes + +- updates wc3 accordion and accordion item docs ([PR #26938](https://github.com/microsoft/fluentui/pull/26938) by brianbrady@microsoft.com) + ## [3.0.0-alpha.7](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.7) Mon, 27 Feb 2023 04:27:02 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 3759989b9e6f9..11a0b8da7d642 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.7", + "version": "3.0.0-alpha.8", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 11704bfce6e4ea24210d1343f8770bb0e45d41d6 Mon Sep 17 00:00:00 2001 From: Ryan Merrill Date: Tue, 28 Feb 2023 17:33:02 -0500 Subject: [PATCH 047/203] Redo of PR of Slider spec after merge error (#26981) * Redo of PR of Slider spec after merge error * Updates API report and beachball file * Generates API report * Redo of PR of Slider spec after merge error * Updates API report and beachball file * Generates API report * Updates API report --- ...-2cdbddf3-5a67-47fc-9baa-da97520b8888.json | 7 ++ .../web-components/src/slider/slider.spec.md | 110 ++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 change/@fluentui-web-components-2cdbddf3-5a67-47fc-9baa-da97520b8888.json create mode 100644 packages/web-components/src/slider/slider.spec.md diff --git a/change/@fluentui-web-components-2cdbddf3-5a67-47fc-9baa-da97520b8888.json b/change/@fluentui-web-components-2cdbddf3-5a67-47fc-9baa-da97520b8888.json new file mode 100644 index 0000000000000..607479227b921 --- /dev/null +++ b/change/@fluentui-web-components-2cdbddf3-5a67-47fc-9baa-da97520b8888.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Redo of PR of Slider spec after merge error", + "packageName": "@fluentui/web-components", + "email": "ryan@ryanmerrill.net", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/src/slider/slider.spec.md b/packages/web-components/src/slider/slider.spec.md new file mode 100644 index 0000000000000..5737f68f67d7c --- /dev/null +++ b/packages/web-components/src/slider/slider.spec.md @@ -0,0 +1,110 @@ +# Slider + +## Component Description + +The Slider component allows users to quickly select a value by dragging an icon across a bar. It is often used when setting values with a relaxed precision such as audio volume and screen brightness. + +## Design Spec + +[Link to Design Spec in Figma](https://www.figma.com/file/IBCBJxEbPKS7CvLHG55Wn9/Slider?node-id=513%3A510&t=hCOhOiQJVCVNVVJP-0) + +## Engineering Spec + +### Inputs + +- @attr size: "small" "medium" | "medium" +- @attr vertical: boolean | false +- @attr current-value: number +- @attr min: number +- @attr max: number +- @attr step: number | 1 + - If set, slider appearance has ticks for each step value +- @attr disabled: boolean | false + +### Outputs + +None + +### Events + +- @change: Fires whenever the slider's value is changed + +### Slots + +- default: child elements such as SliderLabel will be placed in the default slot +- thumb: the draggable element of the slider +- track: the slider's base and used to display the min/max selectable values +- progress-track: the progress indicator when in `range` mode + +### CSS Variables + +None + +### Interactions + +#### track + +- Clicking on the track moves the thumb to the location of mouse click + +## Accessibility + +- [x] Find the matching component through WCAG's patterns: https://www.w3.org/WAI/ARIA/apg/patterns/ + - https://www.w3.org/WAI/ARIA/apg/patterns/slider/ +- [x] Are there any accessibility elements unique to this component? +- [x] List ARIA attributes + - [x] role="slider" in FAST + - [x] aria-valuenow in FAST + - [x] aria-valuemin in FAST + - [x] aria-valuemax in FAST + - [x] aria-orientation (if vertical) in FAST +- [ ] Does the component support 400% zoom? +- [ ] What keyboard behaviors does the component support? + - [ ] Up / Right : Increments slider by Step amount + - [ ] Down / Left: Decrements slider by Step amount + - [ ] PageUp/Up/Right & Shift : Increments the value of the slider by 10 \_ step. + - [ ] PageDown /Down/Left & Shift : Decrements the value of the slider by 10 \_ step. + - [ ] Home : Sets value to the min prop. + - [ ] End : Sets value to the max prop. + +## Preparation + +- [x] [Find the base FAST Component](https://explore.fast.design/components/) this component will inherit from and document + - [FAST Slider Component](https://explore.fast.design/components/fast-slider) +- [x] [Check the Fluent UI React V9 Component Spec](https://github.com/microsoft/fluentui/tree/master/specs) for differences and document + - [Fluent Slider Spec](https://github.com/microsoft/fluentui/blob/master/packages/react-components/react-slider/docs/Spec.md) + - no `defaultValue` or `value` attributes, instead only `current-value` that specifies the selected range of the slider + - `rail` is in Fluent React; `track` is in FAST Foundation + - No value indicators to the left/right of slider in FAST Slider. These should be present in Fluent version. This will be handled through slotting in the the SliderLabel component. + - No default support for the ticks on the slider when `step` is set. This will be handled through slotting in the SliderLabel component. +- [x] [Fluent UI React V9 Storybook](https://aka.ms/fluentui-storybook) for implementation differences and document + - [Fluent React V9 Slider](https://master--628d031b55e942004ac95df1.chromatic.com/?path=/docs/components-slider--default) +- [x] [Open GitHub issues related to component](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#find-open-issues-on-github) + - [Slider](https://master--628d031b55e942004ac95df1.chromatic.com/?path=/docs/components-slider--default) +- [ ] (Optional) [Draft implementation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#draft-implementation) + - [link to draft implementation, if applicable] +- [x] [Component Spec authored](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#component-spec) + - [ ] And [reviewed](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#spec-review) + +## Implementation + +- [ ] Initial conformance and unit tests (validate basic functionality) +- [ ] [Initial documentation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#documentation) + - [ ] [Storybook stories](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#storybook-stories) + - [ ] README.md covering basic usage +- [ ] Uses design tokens for styling +- [ ] Renders correctly in High Contrast mode + +## Validation + +- [ ] [Add tests](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#tests) + - [ ] Unit and conformance tests + - [ ] Bundle size fixtures + - [ ] Performance test scenario + - [ ] Accessibility behavior tests + - [ ] Create an issue and run [manual accessibility tests](https://github.com/microsoft/fluentui/wiki/Manual-Accessibility-Review-Checklist): [link to issue] +- [ ] [Validate with partners](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#validation) +- [ ] [Finalize documentation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#finalize-documentation) + - [ ] Review and add any missing Storybook stories + - [ ] Finalize migration guide + - [ ] In package.json: Remove the alpha/beta tag from the version number in package.json + - [ ] In package.json: Change beachball's `disallowedChangeTypes` to `"major", "prerelease"` From 71f25a2547b1c0df1f8d4df7c67b3d51a878f3c2 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Wed, 1 Mar 2023 04:20:26 +0000 Subject: [PATCH 048/203] applying package updates --- ...ents-2cdbddf3-5a67-47fc-9baa-da97520b8888.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) delete mode 100644 change/@fluentui-web-components-2cdbddf3-5a67-47fc-9baa-da97520b8888.json diff --git a/change/@fluentui-web-components-2cdbddf3-5a67-47fc-9baa-da97520b8888.json b/change/@fluentui-web-components-2cdbddf3-5a67-47fc-9baa-da97520b8888.json deleted file mode 100644 index 607479227b921..0000000000000 --- a/change/@fluentui-web-components-2cdbddf3-5a67-47fc-9baa-da97520b8888.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "Redo of PR of Slider spec after merge error", - "packageName": "@fluentui/web-components", - "email": "ryan@ryanmerrill.net", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 8e683dc66791d..85c21cb093715 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Wed, 01 Mar 2023 04:20:20 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.9", + "version": "3.0.0-alpha.9", + "comments": { + "prerelease": [ + { + "author": "ryan@ryanmerrill.net", + "package": "@fluentui/web-components", + "commit": "d87331975f16754f9debb4e11c6dd4f2b516f130", + "comment": "Redo of PR of Slider spec after merge error" + } + ] + } + }, { "date": "Tue, 28 Feb 2023 04:25:15 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.8", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index c679c5a84be53..b0ea9557ef309 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Tue, 28 Feb 2023 04:25:15 GMT and should not be manually modified. +This log was last generated on Wed, 01 Mar 2023 04:20:20 GMT and should not be manually modified. +## [3.0.0-alpha.9](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.9) + +Wed, 01 Mar 2023 04:20:20 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.8..@fluentui/web-components_v3.0.0-alpha.9) + +### Changes + +- Redo of PR of Slider spec after merge error ([PR #26981](https://github.com/microsoft/fluentui/pull/26981) by ryan@ryanmerrill.net) + ## [3.0.0-alpha.8](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.8) Tue, 28 Feb 2023 04:25:15 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 11a0b8da7d642..ac52978168acd 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.8", + "version": "3.0.0-alpha.9", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 2410855ade96edee7983eed31ad4f636f6c83d53 Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Thu, 2 Mar 2023 10:59:07 -0800 Subject: [PATCH 049/203] web component Radio and RadioGroup spec (#26900) * radio spec init * updates radio spec formatting * adds radio group spec * updates radio specs * updates spec * yarn change --- ...-465472d4-4754-436c-b2eb-4e6931b79ed1.json | 7 + .../web-components/src/radio-group/README.md | 127 +++++++++++++++++ packages/web-components/src/radio/README.md | 133 ++++++++++++++++++ 3 files changed, 267 insertions(+) create mode 100644 change/@fluentui-web-components-465472d4-4754-436c-b2eb-4e6931b79ed1.json create mode 100644 packages/web-components/src/radio-group/README.md create mode 100644 packages/web-components/src/radio/README.md diff --git a/change/@fluentui-web-components-465472d4-4754-436c-b2eb-4e6931b79ed1.json b/change/@fluentui-web-components-465472d4-4754-436c-b2eb-4e6931b79ed1.json new file mode 100644 index 0000000000000..abd96fa13f0bc --- /dev/null +++ b/change/@fluentui-web-components-465472d4-4754-436c-b2eb-4e6931b79ed1.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "adds radio and radio group spec", + "packageName": "@fluentui/web-components", + "email": "brianbrady@microsoft.com", + "dependentChangeType": "none" +} diff --git a/packages/web-components/src/radio-group/README.md b/packages/web-components/src/radio-group/README.md new file mode 100644 index 0000000000000..d80d1ab434f63 --- /dev/null +++ b/packages/web-components/src/radio-group/README.md @@ -0,0 +1,127 @@ +# Radio Group + +> RadioGroup lets people select a single option from two or more Radio items. Use RadioGroup to present all available choices if there's enough space.. + +
+ +## **Design Spec** + +[Link to Radio Design Spec in Figma](https://www.figma.com/file/4XWsJrlpEcuEpUnZbtoIBU/Radio?node-id=1295%3A0&t=2wXnjT4ybxIxT6wu-0) + +
+ +## **Engineering Spec** + +As defined by the [W3C](https://www.w3.org/WAI/ARIA/apg/patterns/radio/).. + +> A radio group is a set of checkable buttons, known as radio buttons, where no more than one of the buttons can be checked at a time. Some implementations may initialize the set with all buttons in the unchecked state in order to force the user to check one of the buttons before moving past a certain point in the workflow. + +### Use Case + +Used anywhere an author might group a list of radio options. + +
+ +## Class: `RadioGroup` + +
+ +### **Component Name** + +
+ +`fluent-radio-group` + +
+ +### **Fields** + +| Name | Privacy | Type | Default | Description | +| ------------- | ------- | ------------------------ | ------------ | ----------------------------------------------------------------------------------------------------- | +| `disabled` | public | `boolean` | `false` | Disables the radio group and child radios. | +| `name` | public | `string` | | The name of the radio group. Setting this value will set the name value for all child radio elements. | +| `value` | public | `string` | | The value of the checked radio. | +| `orientation` | public | `horizontal \| vertical` | `horizontal` | The orientation of the group | +| default slot | public | `HTMLElement[]` | | The default slot expecting Radio items | + +
+ +### **Methods** + +| Name | Privacy | Description | Parameters | Return | Inherited From | +| -------------- | --------- | ----------- | ---------- | ------ | -------------- | +| `nameChanged` | protected | | | `void` | | +| `valueChanged` | protected | | | `void` | | + +
+ +### **Events** + +| Name | Type | Description | +| -------- | ---- | ---------------------------------------------------- | +| `change` | | Fires a custom 'change' event when the value changes | + +
+ +### **Attributes** + +| Name | Field | Inherited From | +| ------------- | ----------- | -------------- | +| `disabled` | disabled | | +| `named` | name | | +| `value` | value | | +| `orientation` | orientation | | + +
+ +### **Slots** + +| Name | Description | +| ----- | --------------------------------- | +| | The default slot for radios | +| label | Provide label for the radio group | + +
+
+
+ +### **Suggested Template** + +`radioGroupTemplate` from FastFoundation + +## **Accessibility** + +[W3 Radio Spec](https://www.w3.org/WAI/ARIA/apg/patterns/radio/) + +
+ +### **WAI-ARIA Roles, States, and Properties** + +| Attributes | value | Description | +| ----------------- | ----- | ---------------------------------------- | +| `aria-labelledby` | | used to associate a label with the group | + +
+
+
+ +## **Preparation** + +
+ +### **Fluent Web Component v3 v.s Fluent React 9** + +
+ +**Component and Slot Mapping** + +| Fluent UI React 9 | Fluent Web Components 3 | +| ----------------- | ----------------------- | +| `` | `` | + +
+ +**Property Mapping** +| Fluent UI React 9 | Fluent Web Components 3 | Description of difference | +|-------------------|------------------------ |---------------------------| +| `layout` | `orientation` | React implementation requires user to pass either `"horizontal"` or `"horizontal-stacked"` through `layout` prop.
WC3 implementation requires user to either pass `"vertical"` or "`horizontal"` through `orientation` attribute. diff --git a/packages/web-components/src/radio/README.md b/packages/web-components/src/radio/README.md new file mode 100644 index 0000000000000..10152def1bbc1 --- /dev/null +++ b/packages/web-components/src/radio/README.md @@ -0,0 +1,133 @@ +# Radio + +> Radio buttons allow users to select a single option from two or more choices. Radio buttons are typically rendered as small circles, which are filled or highlighted when selected. + +
+ +## **Design Spec** + +[Link to Radio Design Spec in Figma](https://www.figma.com/file/4XWsJrlpEcuEpUnZbtoIBU/Radio?node-id=1295%3A1&t=YOHXLUSK493rMiyh-0) + +
+ +## **Engineering Spec** + +Fluent WC3 Radio is a form associated component that extends from the FAST Radio [FAST Radio](https://explore.fast.design/components/fast-radio) and is intended to be as close to the Fluent UI React 9 Menu implementation as possible. However, due to the nature of web components there will not be 100% parity between the two. + +### Use Case + +Used anywhere an author might otherwise use an input[type="radio"]. Used to facilitate choice where only one choice is acceptable. + +
+ +## Class: `Radio` + +
+ +### **Component Name** + +
+ +`fluent-radio` + +
+ +### **Variables** + +
+ +### **Fields** + +| Name | Privacy | Type | Default | Description | +| --------------- | ------- | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | public | `string` | | The name of the radio. See [name attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefname) for more info. | +| `disabled` | public | `boolean` | | Sets disabled state for radio | +| `labelPosition` | public | `"after"` `"below"` | `"below"` | The position of the label relative to the radio indicator. | +| `checked` | public | `boolean` | `false` | When true, radio button will be checked | + +
+ +### **Methods** + +
+ +### **Events** + +| Name | Type | Inherited From | +| -------- | ---- | -------------- | +| `change` | | | + +
+ +### **Attributes** + +| Name | Field | +| ---------------- | ------------- | +| `name` | name | +| `disabled` | disabled | +| `label-position` | labelPosition | +| `checked` | checked | + +
+ +### **Slots** + +| Name | Description | +| ------------------- | -------------------------------------- | +| `checked-indicator` | The checked indicator | +| | Default slotted content for label text | + +
+
+
+ +### **Suggested Template** + +
+ +`radioTemplate` from FastFoundation + +
+
+
+ +## **Accessibility** + +[W3 Radio Spec](https://www.w3.org/WAI/ARIA/apg/patterns/radio/) + +
+ +### **WAI-ARIA Roles, States, and Properties** + +| Attributes | value | Description | +| --------------- | ------- | ----------------------------------- | +| `role` | `radio` | +| `aria-checked` | | the checked state of the component | +| `aria-required` | | the required state of the component | +| `aria-disabled` | | the disabled state of the component | +| `tabindex` | `0` | | + +
+
+
+ +## **Preparation** + +
+ +### **Fluent Web Component v3 v.s Fluent React 9** + +
+ +**Component and Slot Mapping** + +| Fluent UI React 9 | Fluent Web Components 3 | +| ----------------- | ----------------------- | +| `` | `` | + +
+ +**Property Mapping** +| Fluent UI React 9 | Fluent Web Components 3 | Description of difference | +|-------------------|------------------------ |---------------------------| +| `prop label` | default slotted content | React implementation requires user to pass a string through the `label` prop on the Radio component

The web component implementation requires users to pass the label text through the default slotted content From 0d524fb714d051b16ac0305c54ba7cd2cc88d48d Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Fri, 3 Mar 2023 04:23:07 +0000 Subject: [PATCH 050/203] applying package updates --- ...ents-465472d4-4754-436c-b2eb-4e6931b79ed1.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 change/@fluentui-web-components-465472d4-4754-436c-b2eb-4e6931b79ed1.json diff --git a/change/@fluentui-web-components-465472d4-4754-436c-b2eb-4e6931b79ed1.json b/change/@fluentui-web-components-465472d4-4754-436c-b2eb-4e6931b79ed1.json deleted file mode 100644 index abd96fa13f0bc..0000000000000 --- a/change/@fluentui-web-components-465472d4-4754-436c-b2eb-4e6931b79ed1.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "adds radio and radio group spec", - "packageName": "@fluentui/web-components", - "email": "brianbrady@microsoft.com", - "dependentChangeType": "none" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 85c21cb093715..21365b772d9af 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Fri, 03 Mar 2023 04:23:00 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.9", + "version": "3.0.0-alpha.9", + "comments": { + "none": [ + { + "author": "brianbrady@microsoft.com", + "package": "@fluentui/web-components", + "commit": "9ae245574502f15ed372dc37b0374883f45ccdf2", + "comment": "adds radio and radio group spec" + } + ] + } + }, { "date": "Wed, 01 Mar 2023 04:20:20 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.9", From c2054a8b596f1e5ef324c8a461cec4f8ae95c9d9 Mon Sep 17 00:00:00 2001 From: Ryan Merrill Date: Mon, 6 Mar 2023 16:00:51 -0500 Subject: [PATCH 051/203] Adds SliderLabel Spec and Folder (#27001) * Adds SliderLabel spec and folder * Creates change and api-report * Creates change and api-report * Update change/@fluentui-web-components-085483f0-a46f-4531-b8c4-218a2e78461b.json Co-authored-by: Miroslav Stastny * Regenerates API Report --------- Co-authored-by: Miroslav Stastny --- ...-085483f0-a46f-4531-b8c4-218a2e78461b.json | 7 ++ .../src/slider-label/slider-label.spec.md | 74 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 change/@fluentui-web-components-085483f0-a46f-4531-b8c4-218a2e78461b.json create mode 100644 packages/web-components/src/slider-label/slider-label.spec.md diff --git a/change/@fluentui-web-components-085483f0-a46f-4531-b8c4-218a2e78461b.json b/change/@fluentui-web-components-085483f0-a46f-4531-b8c4-218a2e78461b.json new file mode 100644 index 0000000000000..ecc100bc522ee --- /dev/null +++ b/change/@fluentui-web-components-085483f0-a46f-4531-b8c4-218a2e78461b.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "Adds SliderLabel spec and folder", + "packageName": "@fluentui/web-components", + "email": "ryan@ryanmerrill.net", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/src/slider-label/slider-label.spec.md b/packages/web-components/src/slider-label/slider-label.spec.md new file mode 100644 index 0000000000000..025c67ccc29b1 --- /dev/null +++ b/packages/web-components/src/slider-label/slider-label.spec.md @@ -0,0 +1,74 @@ +# SliderLabel + +## Description + +A label element intended to be used with the Slider component. Ability to hide the mark or provide a custom label element is baked in. + +## Design Spec + +[Link to Design Spec in Figma](https://www.figma.com/file/IBCBJxEbPKS7CvLHG55Wn9/Slider?node-id=1639%3A12700&t=1cp8zLuAuXd8cLBk-11) + +## Engineering Spec + +### Inputs + +- @attr position | number - The location of the label relative to the minimum and maximum values of the slider +- @attr hide-mark | boolean - Whether or not to hide the mark on the rail + +### Slots + +- label - replaceable with custom DOM element(s) + +### CSS Parts + +- label - how to style the label element by each label mark + +## Accessibility + +- [x] Find the matching component through WCAG's patterns: https://www.w3.org/WAI/ARIA/apg/patterns/ +- [x] Are there any accessibility elements unique to this component? + - No +- [x] Does the component support 400% zoom? + +## Preparation + +- [x] [Find the base FAST Component](https://explore.fast.design/components/) this component will inherit from and document + - [Slider + SliderLabel Spec](https://github.com/microsoft/fast/blob/master/packages/web-components/fast-foundation/src/slider/slider.spec.md) +- [x] [Check the Fluent UI React V9 Component Spec](https://github.com/microsoft/fluentui/tree/master/specs) for differences and document + - [Link to Spec](https://github.com/microsoft/fluentui/blob/master/specs/Slider.md) + - SliderLabel doesn't exist as an independent component in Fluent +- [x] [Fluent UI React V9 Storybook](https://aka.ms/fluentui-storybook) for implementation differences and document + - [Link to Storybook Component](https://master--628d031b55e942004ac95df1.chromatic.com/?path=/docs/components-slider--default) + - Fluent React SliderLabel doesn't allow the display of individual values on each tick mark on rail + - Fluent React Slider only displays value of the labels on the ends of the rail + - SliderLabel doesn't exist as an independent component in Fluent +- [x] [Open GitHub issues related to component](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#find-open-issues-on-github) + - [link to each issue] +- [ ] (Optional) [Draft implementation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#draft-implementation) + - [link to draft implementation, if applicable] +- [ ] [Component Spec authored](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#component-spec) and [reviewed](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#spec-review) + +## Implementation + +- [ ] Initial conformance and unit tests (validate basic functionality) +- [ ] [Initial documentation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#documentation) + - [ ] [Storybook stories](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#storybook-stories) + - [ ] README.md covering basic usage +- [ ] [Component released as unstable](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#unstable-release) from `@fluentui/web-components/unstable` +- [ ] Uses design tokens for styling +- [ ] Renders correctly in High Contrast mode + +## Validation + +- [ ] [Add tests](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#tests) + - [ ] Unit and conformance tests + - [ ] Bundle size fixtures + - [ ] Performance test scenario + - [ ] Accessibility behavior tests + - [ ] Create an issue and run [manual accessibility tests](https://github.com/microsoft/fluentui/wiki/Manual-Accessibility-Review-Checklist): [link to issue] +- [ ] [Validate with partners](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#validation) +- [ ] [Finalize documentation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#finalize-documentation) + - [ ] Review and add any missing storybook stories + - [ ] Finalize migration guide + - [ ] In package.json: Remove the alpha/beta tag from the version number in package.json + - [ ] In package.json: Change beachball's `disallowedChangeTypes` to `"major", "prerelease"` From adeec7b8ceaca278cd7540c0dc2f3a516a94176b Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Tue, 7 Mar 2023 04:24:58 +0000 Subject: [PATCH 052/203] applying package updates --- ...ents-085483f0-a46f-4531-b8c4-218a2e78461b.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 change/@fluentui-web-components-085483f0-a46f-4531-b8c4-218a2e78461b.json diff --git a/change/@fluentui-web-components-085483f0-a46f-4531-b8c4-218a2e78461b.json b/change/@fluentui-web-components-085483f0-a46f-4531-b8c4-218a2e78461b.json deleted file mode 100644 index ecc100bc522ee..0000000000000 --- a/change/@fluentui-web-components-085483f0-a46f-4531-b8c4-218a2e78461b.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "Adds SliderLabel spec and folder", - "packageName": "@fluentui/web-components", - "email": "ryan@ryanmerrill.net", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 21365b772d9af..e552948238708 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Tue, 07 Mar 2023 04:24:51 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.9", + "version": "3.0.0-alpha.9", + "comments": { + "none": [ + { + "author": "ryan@ryanmerrill.net", + "package": "@fluentui/web-components", + "commit": "07c70c3cb2253817e70e9b1c4615aee7e69a1816", + "comment": "Adds SliderLabel spec and folder" + } + ] + } + }, { "date": "Fri, 03 Mar 2023 04:23:00 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.9", From 5898ff32310e06a0b85340f24ca413f17cdb9ae5 Mon Sep 17 00:00:00 2001 From: Levi Thomason Date: Wed, 8 Mar 2023 08:27:29 -0800 Subject: [PATCH 053/203] Web Component v3 Stories (#27049) * Flatten badge stories in sidebar * undo badge flattening * add divider stories * progress stories * spinner stories * switch stories * text stories * remove text as story --- .../src/divider/divider.stories.ts | 54 ++++++++++- .../src/progress-bar/progress-bar.stories.ts | 74 +++++++++++++- .../src/spinner/spinner.stories.ts | 34 ++++++- .../src/switch/switch.stories.ts | 18 ++++ .../web-components/src/text/text.stories.ts | 97 +++++++++++++++++++ 5 files changed, 270 insertions(+), 7 deletions(-) diff --git a/packages/web-components/src/divider/divider.stories.ts b/packages/web-components/src/divider/divider.stories.ts index 95bb0ce140666..268729555493a 100644 --- a/packages/web-components/src/divider/divider.stories.ts +++ b/packages/web-components/src/divider/divider.stories.ts @@ -9,7 +9,7 @@ type DividerStoryArgs = Args & FluentDivider; type DividerStoryMeta = Meta; const dividerTemplate = html` -
+
x.alignContent} appearance=${x => x.appearance} @@ -23,7 +23,7 @@ const dividerTemplate = html` `; const dividerSvgTemplate = html` -
+
` + + Wrap your content in an element to render + +`); +export const AlignContent = renderComponent(html` +
+
center
+
start
+
end
+
+`); +export const Appearance = renderComponent(html` +
+
strong
+
brand
+
subtle
+
default
+
+`); +export const Role = renderComponent(html` +
+
separator
+
presentation
+
+`); + +// TODO: there is no visual difference between inset="true" and inset="false" +export const Inset = renderComponent(html` +
+
I'm inset from the edges
+
Default
+
+`); +export const Orientation = renderComponent(html` +
+
vertical
+
+
horizontal
+
+`); + +// +// Extra stories - These stories are in addition to the story for each attribute. +// export const DividerWithSvg = renderComponent(dividerSvgTemplate).bind({}); export const VerticalDividerWithSvg = renderComponent(dividerSvgVerticalTemplate).bind({}); diff --git a/packages/web-components/src/progress-bar/progress-bar.stories.ts b/packages/web-components/src/progress-bar/progress-bar.stories.ts index 5d609ff780d73..77e2347757131 100644 --- a/packages/web-components/src/progress-bar/progress-bar.stories.ts +++ b/packages/web-components/src/progress-bar/progress-bar.stories.ts @@ -64,6 +64,76 @@ export default { export const Progress = renderComponent(storyTemplate).bind({}); -export const ProgressIndeterminate = renderComponent(html` - +// +// Attribute stories +// + +export const Max = renderComponent(html` +
+

+ 3 of 10 + +

+

+ 3 o 5 + +

+
+`); + +export const Value = renderComponent(html` +
+ 0 + 25 + + 50 + + 75 + + 100 + +
+`); + +export const Thickness = renderComponent(html` +
+

+ medium + +

+

+ large + +

+
+`); + +export const Shape = renderComponent(html` +
+

+ rounded + +

+

+ square + +

+
+`); + +export const ValidationState = renderComponent(html` +
+

+ success + +

+

+ warning + +

+

+ error + +

+
`); diff --git a/packages/web-components/src/spinner/spinner.stories.ts b/packages/web-components/src/spinner/spinner.stories.ts index e9f607798711b..0373b81f304b5 100644 --- a/packages/web-components/src/spinner/spinner.stories.ts +++ b/packages/web-components/src/spinner/spinner.stories.ts @@ -46,8 +46,36 @@ export default { export const Spinner = renderComponent(storyTemplate).bind({}); -export const SpinnerInverted = renderComponent(html` -
- +// +// Attribute stories +// + +export const Appearance = renderComponent(html` +
+
+ primary + +
+
+ inverted + +
+
+`); + +export const Size = renderComponent(html` +
+ tiny + + extra-small + + small + + medium + + large + + extra-large +
`); diff --git a/packages/web-components/src/switch/switch.stories.ts b/packages/web-components/src/switch/switch.stories.ts index 13ece9c67f1c0..57c9e2a9fee1b 100644 --- a/packages/web-components/src/switch/switch.stories.ts +++ b/packages/web-components/src/switch/switch.stories.ts @@ -86,3 +86,21 @@ export default { } as SwitchStoryMeta; export const Switch = renderComponent(storyTemplate).bind({}); + +// +// Attribute stories +// + +export const Checked = renderComponent(html`Checked`); + +export const Disabled = renderComponent(html`Disabled`); + +export const Required = renderComponent(html`Required`); + +export const LabelPosition = renderComponent(html` +
+ before + above + after +
+`); diff --git a/packages/web-components/src/text/text.stories.ts b/packages/web-components/src/text/text.stories.ts index 9149311851f61..c5f9aa31445c7 100644 --- a/packages/web-components/src/text/text.stories.ts +++ b/packages/web-components/src/text/text.stories.ts @@ -118,3 +118,100 @@ export default { } as TextStoryMeta; export const Text = renderComponent(storyTemplate).bind({}); + +// +// Attribute stories +// + +export const Nowrap = renderComponent(html` + +
+ This text will not wrap lines when it overflows the container. +
+
+`); + +export const Truncate = renderComponent(html` + +
+ Setting truncate and nowrap will truncate when it overflows the container. +
+
+`); + +export const Italic = renderComponent(html` + + Italics are emphasized text. + +`); + +export const Underline = renderComponent(html` + + Underlined text draws the reader's attention to the words. + +`); + +export const Strikethrough = renderComponent(html` + + Strikethrough text is used to indicate something that is no longer relevant. + +`); + +export const Block = renderComponent(html` + + Fluent text is inline by default. Setting + block + will make it behave as a block element. + +`); + +export const Size = renderComponent(html` +
+ 100 + 200 + 300 + 400 + 500 + 600 + 700 + 800 + 900 + 1000 +
+`); + +export const Weight = renderComponent(html` +
+ This text is regular. + This text is medium. + This text is semibold. + This text is bold. +
+`); + +export const Align = renderComponent(html` +
+ + Start aligned block. + + + End aligned block. + + + Center aligned block. + + + Justify aligned block text stretches wrapped lines to meet container edges. + +
+`); + +export const Font = renderComponent(html` +
+ Font base. + Font numeric 0123456789. + Font monospace. +
+`); From e5fa5211b7567dd47cdebbf6e850c82cefe1d804 Mon Sep 17 00:00:00 2001 From: Jeff Smith <37851214+eljefe223@users.noreply.github.com> Date: Wed, 8 Mar 2023 14:40:19 -0800 Subject: [PATCH 054/203] fix: [text] block breaks the style attribute (#27129) * fix: [text] block breaks the style attribute * chnage files * addresed comments * Update packages/web-components/src/text/text.styles.ts Co-authored-by: Chris Holt * addressed pr comments --------- Co-authored-by: Chris Holt --- ...eb-components-91a1543a-10b0-4b10-9d32-0535f7a8e631.json | 7 +++++++ packages/web-components/src/text/text.styles.ts | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 change/@fluentui-web-components-91a1543a-10b0-4b10-9d32-0535f7a8e631.json diff --git a/change/@fluentui-web-components-91a1543a-10b0-4b10-9d32-0535f7a8e631.json b/change/@fluentui-web-components-91a1543a-10b0-4b10-9d32-0535f7a8e631.json new file mode 100644 index 0000000000000..e96167ea0483c --- /dev/null +++ b/change/@fluentui-web-components-91a1543a-10b0-4b10-9d32-0535f7a8e631.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "fix: [text] block breaks the style attribute", + "packageName": "@fluentui/web-components", + "email": "jes@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/src/text/text.styles.ts b/packages/web-components/src/text/text.styles.ts index cfe208b822005..232555a9d2e0d 100644 --- a/packages/web-components/src/text/text.styles.ts +++ b/packages/web-components/src/text/text.styles.ts @@ -42,12 +42,13 @@ export const styles = css` line-height: ${lineHeightBase300}; font-weight: ${fontWeightRegular}; text-align: start; - display: inline; white-space: normal; overflow: visible; text-overflow: clip; margin: 0; + display: inline; } + :host([nowrap]) ::slotted(*) { white-space: nowrap; overflow: hidden; @@ -55,6 +56,7 @@ export const styles = css` :host([truncate]) ::slotted(*) { text-overflow: ellipsis; } + :host([block]), :host([block]) ::slotted(*) { display: block; } From 197a16bd8b226f7fffe3ba9adacafb16fda18091 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Thu, 9 Mar 2023 04:19:52 +0000 Subject: [PATCH 055/203] applying package updates --- ...ents-91a1543a-10b0-4b10-9d32-0535f7a8e631.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) delete mode 100644 change/@fluentui-web-components-91a1543a-10b0-4b10-9d32-0535f7a8e631.json diff --git a/change/@fluentui-web-components-91a1543a-10b0-4b10-9d32-0535f7a8e631.json b/change/@fluentui-web-components-91a1543a-10b0-4b10-9d32-0535f7a8e631.json deleted file mode 100644 index e96167ea0483c..0000000000000 --- a/change/@fluentui-web-components-91a1543a-10b0-4b10-9d32-0535f7a8e631.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "fix: [text] block breaks the style attribute", - "packageName": "@fluentui/web-components", - "email": "jes@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index e552948238708..485faac1628aa 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Thu, 09 Mar 2023 04:19:45 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.10", + "version": "3.0.0-alpha.10", + "comments": { + "prerelease": [ + { + "author": "jes@microsoft.com", + "package": "@fluentui/web-components", + "commit": "443b8d8e35429ffbabda35cbe7d4704adaaf8ab4", + "comment": "fix: [text] block breaks the style attribute" + } + ] + } + }, { "date": "Tue, 07 Mar 2023 04:24:51 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.9", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index b0ea9557ef309..5238de20585c8 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Wed, 01 Mar 2023 04:20:20 GMT and should not be manually modified. +This log was last generated on Thu, 09 Mar 2023 04:19:45 GMT and should not be manually modified. +## [3.0.0-alpha.10](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.10) + +Thu, 09 Mar 2023 04:19:45 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.9..@fluentui/web-components_v3.0.0-alpha.10) + +### Changes + +- fix: [text] block breaks the style attribute ([PR #27129](https://github.com/microsoft/fluentui/pull/27129) by jes@microsoft.com) + ## [3.0.0-alpha.9](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.9) Wed, 01 Mar 2023 04:20:20 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index ac52978168acd..2fab6b0c1e244 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 2e91be9c759f908f0c65cd9fd66f6c221dd0b55f Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Mon, 13 Mar 2023 14:47:40 -0700 Subject: [PATCH 056/203] update FAST dependencies (#27187) --- ...s-54c7cd29-29dc-46c9-8324-465b8c1b5eac.json | 7 +++++++ packages/web-components/package.json | 4 ++-- yarn.lock | 18 +++++++++--------- 3 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 change/@fluentui-web-components-54c7cd29-29dc-46c9-8324-465b8c1b5eac.json diff --git a/change/@fluentui-web-components-54c7cd29-29dc-46c9-8324-465b8c1b5eac.json b/change/@fluentui-web-components-54c7cd29-29dc-46c9-8324-465b8c1b5eac.json new file mode 100644 index 0000000000000..513eeec26c229 --- /dev/null +++ b/change/@fluentui-web-components-54c7cd29-29dc-46c9-8324-465b8c1b5eac.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "update FAST dependencies to latest package versions", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 2fab6b0c1e244..f59477f4bf5f6 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -125,8 +125,8 @@ "typescript": "4.7.4" }, "dependencies": { - "@microsoft/fast-element": "^2.0.0-beta.21", - "@microsoft/fast-foundation": "^3.0.0-alpha.25", + "@microsoft/fast-element": "^2.0.0-beta.22", + "@microsoft/fast-foundation": "^3.0.0-alpha.26", "@microsoft/fast-web-utilities": "^6.0.0", "@fluentui/tokens": "1.0.0-alpha.2", "tslib": "^2.1.0" diff --git a/yarn.lock b/yarn.lock index b606c143f151f..34b7b512edef7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2657,18 +2657,18 @@ eslint-plugin-react "7.24.0" eslint-plugin-security "1.4.0" -"@microsoft/fast-element@^2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@microsoft/fast-element/-/fast-element-2.0.0-beta.21.tgz#98710d92f84f3e7f204514c194cbcf3ef8a485a2" - integrity sha512-cyM7ieXW82JqgHK3Es9Gu8EvtZOjqd0adhceoibQsdU9OpJVqKbriNNGDC7+EuGkMrczo2AnIIhP3/mGQ85faQ== +"@microsoft/fast-element@^2.0.0-beta.22": + version "2.0.0-beta.22" + resolved "https://registry.yarnpkg.com/@microsoft/fast-element/-/fast-element-2.0.0-beta.22.tgz#e8a508544b2af9db387e9e728d0de1fb9b8f1a12" + integrity sha512-uyNiiTp59BN0uiRE5f2avwTR5vNoPavTFvPQ+v8UcWgL4Zi206dTfIOEH/hR0eeY8Jw3w0C6FHNSc/ehetkzWg== -"@microsoft/fast-foundation@^3.0.0-alpha.25": - version "3.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/@microsoft/fast-foundation/-/fast-foundation-3.0.0-alpha.25.tgz#7098318b1e9c312085c5d7bd15dc4ce19c89f85a" - integrity sha512-W3MpIxJvF3x14yWWZFVi3BXIK9JbzksLgWaQxlEhHaSwYwUDb2yaWwXJby6ZOKZa2c7ns51rv4xGTPmvaGUwag== +"@microsoft/fast-foundation@^3.0.0-alpha.26": + version "3.0.0-alpha.26" + resolved "https://registry.yarnpkg.com/@microsoft/fast-foundation/-/fast-foundation-3.0.0-alpha.26.tgz#eb21b5f9ee5d4dccf17da1e709a78775ce1278ad" + integrity sha512-78UJIbS20lCQ9rOyUZMwjXIeEDFBjJZM0DJ7bYUIXgx7JDXygYi8RxnmCFiO0h9XABubiuOJrGDJtqro5sgS7g== dependencies: "@floating-ui/dom" "^1.0.3" - "@microsoft/fast-element" "^2.0.0-beta.21" + "@microsoft/fast-element" "^2.0.0-beta.22" "@microsoft/fast-web-utilities" "^6.0.0" tabbable "^5.2.0" tslib "^2.4.0" From 79c5aa69047b7b2878b6c1aee4f941ee60d59b6e Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Mon, 13 Mar 2023 15:29:00 -0700 Subject: [PATCH 057/203] (web-components): add css containment to v3 components (#27190) * add css containment to custom elements * add css containment to existing web components --- ...eb-components-904258a8-cd16-4d42-be2e-d6179a4afd76.json | 7 +++++++ .../src/accordion-item/accordion-item.styles.ts | 1 + packages/web-components/src/accordion/accordion.styles.ts | 1 + packages/web-components/src/avatar/avatar.styles.ts | 1 + packages/web-components/src/divider/divider.styles.ts | 4 ++++ packages/web-components/src/image/image.styles.ts | 4 ++++ .../web-components/src/progress-bar/progress-bar.styles.ts | 1 + packages/web-components/src/spinner/spinner.styles.ts | 1 + .../web-components/src/styles/partials/badge.partials.ts | 1 + packages/web-components/src/switch/switch.styles.ts | 1 + packages/web-components/src/text/text.styles.ts | 4 ++++ 11 files changed, 26 insertions(+) create mode 100644 change/@fluentui-web-components-904258a8-cd16-4d42-be2e-d6179a4afd76.json diff --git a/change/@fluentui-web-components-904258a8-cd16-4d42-be2e-d6179a4afd76.json b/change/@fluentui-web-components-904258a8-cd16-4d42-be2e-d6179a4afd76.json new file mode 100644 index 0000000000000..186136889e93e --- /dev/null +++ b/change/@fluentui-web-components-904258a8-cd16-4d42-be2e-d6179a4afd76.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Adds css containment to implemented web components", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/src/accordion-item/accordion-item.styles.ts b/packages/web-components/src/accordion-item/accordion-item.styles.ts index 8ff807e33c348..85ade10ee7ee6 100644 --- a/packages/web-components/src/accordion-item/accordion-item.styles.ts +++ b/packages/web-components/src/accordion-item/accordion-item.styles.ts @@ -28,6 +28,7 @@ export const styles = css` :host { max-width: fit-content; + contain: content; } .heading { diff --git a/packages/web-components/src/accordion/accordion.styles.ts b/packages/web-components/src/accordion/accordion.styles.ts index 27ef26a8101e8..6bb015842bfdd 100644 --- a/packages/web-components/src/accordion/accordion.styles.ts +++ b/packages/web-components/src/accordion/accordion.styles.ts @@ -7,5 +7,6 @@ export const styles = css` :host { flex-direction: column; width: 100%; + contain: content; } `; diff --git a/packages/web-components/src/avatar/avatar.styles.ts b/packages/web-components/src/avatar/avatar.styles.ts index 50604d331c711..abb51b95d6e95 100644 --- a/packages/web-components/src/avatar/avatar.styles.ts +++ b/packages/web-components/src/avatar/avatar.styles.ts @@ -131,6 +131,7 @@ export const styles = css` border-radius: ${borderRadiusCircular}; color: ${colorNeutralForeground3}; background-color: ${colorNeutralBackground6}; + contain: layout style; } .default-icon, diff --git a/packages/web-components/src/divider/divider.styles.ts b/packages/web-components/src/divider/divider.styles.ts index e302ab9271da0..f65b9d326334f 100644 --- a/packages/web-components/src/divider/divider.styles.ts +++ b/packages/web-components/src/divider/divider.styles.ts @@ -21,6 +21,10 @@ import { export const styles = css` ${display('flex')} + :host { + contain: content; + } + :host::after, :host::before { align-self: center; diff --git a/packages/web-components/src/image/image.styles.ts b/packages/web-components/src/image/image.styles.ts index 34c04cf72590e..8437b18943ef9 100644 --- a/packages/web-components/src/image/image.styles.ts +++ b/packages/web-components/src/image/image.styles.ts @@ -6,6 +6,10 @@ import { borderRadiusCircular, colorNeutralStroke2, shadow4, strokeWidthThin } f * @public */ export const styles = css` + :host { + contain: content; + } + :host ::slotted(img) { box-sizing: border-box; min-height: 8px; diff --git a/packages/web-components/src/progress-bar/progress-bar.styles.ts b/packages/web-components/src/progress-bar/progress-bar.styles.ts index 281d19ffb5545..2cbab1d9bb757 100644 --- a/packages/web-components/src/progress-bar/progress-bar.styles.ts +++ b/packages/web-components/src/progress-bar/progress-bar.styles.ts @@ -24,6 +24,7 @@ export const styles = css` height: 2px; overflow-x: hidden; border-radius: ${borderRadiusMedium}; + contain: content; } :host([thickness='large']), diff --git a/packages/web-components/src/spinner/spinner.styles.ts b/packages/web-components/src/spinner/spinner.styles.ts index c4061520382f1..47fcafd82ba85 100644 --- a/packages/web-components/src/spinner/spinner.styles.ts +++ b/packages/web-components/src/spinner/spinner.styles.ts @@ -10,6 +10,7 @@ export const styles = css` align-items: center; height: 32px; width: 32px; + contain: content; } :host([size='tiny']) { height: 20px; diff --git a/packages/web-components/src/styles/partials/badge.partials.ts b/packages/web-components/src/styles/partials/badge.partials.ts index cb1263e59d458..8eb4c7be7cde1 100644 --- a/packages/web-components/src/styles/partials/badge.partials.ts +++ b/packages/web-components/src/styles/partials/badge.partials.ts @@ -69,6 +69,7 @@ export const badgeBaseStyles = css.partial` border-color: ${colorTransparentStroke}; background-color: ${colorBrandBackground}; color: ${colorNeutralForegroundOnBrand}; + contain: content; } ::slotted(svg) { diff --git a/packages/web-components/src/switch/switch.styles.ts b/packages/web-components/src/switch/switch.styles.ts index d9ba3cf838bb1..4d7bee90954f4 100644 --- a/packages/web-components/src/switch/switch.styles.ts +++ b/packages/web-components/src/switch/switch.styles.ts @@ -40,6 +40,7 @@ export const styles = css` flex-direction: row-reverse; outline: none; user-select: none; + contain: content; } :host([label-position='before']) { flex-direction: row; diff --git a/packages/web-components/src/text/text.styles.ts b/packages/web-components/src/text/text.styles.ts index 232555a9d2e0d..8593b9ee07011 100644 --- a/packages/web-components/src/text/text.styles.ts +++ b/packages/web-components/src/text/text.styles.ts @@ -36,6 +36,10 @@ import { export const styles = css` ${display('inline')} + :host { + contain: content; + } + ::slotted(*) { font-family: ${fontFamilyBase}; font-size: ${fontSizeBase300}; From 3f0d57ab0adbe268c35c0b0bd917d2c1daa369ed Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Tue, 14 Mar 2023 04:21:29 +0000 Subject: [PATCH 058/203] applying package updates --- ...-54c7cd29-29dc-46c9-8324-465b8c1b5eac.json | 7 ------- ...-904258a8-cd16-4d42-be2e-d6179a4afd76.json | 7 ------- packages/web-components/CHANGELOG.json | 21 +++++++++++++++++++ packages/web-components/CHANGELOG.md | 12 ++++++++++- packages/web-components/package.json | 2 +- 5 files changed, 33 insertions(+), 16 deletions(-) delete mode 100644 change/@fluentui-web-components-54c7cd29-29dc-46c9-8324-465b8c1b5eac.json delete mode 100644 change/@fluentui-web-components-904258a8-cd16-4d42-be2e-d6179a4afd76.json diff --git a/change/@fluentui-web-components-54c7cd29-29dc-46c9-8324-465b8c1b5eac.json b/change/@fluentui-web-components-54c7cd29-29dc-46c9-8324-465b8c1b5eac.json deleted file mode 100644 index 513eeec26c229..0000000000000 --- a/change/@fluentui-web-components-54c7cd29-29dc-46c9-8324-465b8c1b5eac.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "update FAST dependencies to latest package versions", - "packageName": "@fluentui/web-components", - "email": "chhol@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-904258a8-cd16-4d42-be2e-d6179a4afd76.json b/change/@fluentui-web-components-904258a8-cd16-4d42-be2e-d6179a4afd76.json deleted file mode 100644 index 186136889e93e..0000000000000 --- a/change/@fluentui-web-components-904258a8-cd16-4d42-be2e-d6179a4afd76.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "Adds css containment to implemented web components", - "packageName": "@fluentui/web-components", - "email": "chhol@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 485faac1628aa..c8f84f428aaa3 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,27 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Tue, 14 Mar 2023 04:21:22 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.11", + "version": "3.0.0-alpha.11", + "comments": { + "prerelease": [ + { + "author": "chhol@microsoft.com", + "package": "@fluentui/web-components", + "commit": "6e51be008ee479451431421eaf2e3e63744b6d5c", + "comment": "update FAST dependencies to latest package versions" + }, + { + "author": "chhol@microsoft.com", + "package": "@fluentui/web-components", + "commit": "fc86569d1d96d6deff9188fa0702d173150dd5dd", + "comment": "Adds css containment to implemented web components" + } + ] + } + }, { "date": "Thu, 09 Mar 2023 04:19:45 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.10", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index 5238de20585c8..317265b3bed6d 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,19 @@ # Change Log - @fluentui/web-components -This log was last generated on Thu, 09 Mar 2023 04:19:45 GMT and should not be manually modified. +This log was last generated on Tue, 14 Mar 2023 04:21:22 GMT and should not be manually modified. +## [3.0.0-alpha.11](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.11) + +Tue, 14 Mar 2023 04:21:22 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.10..@fluentui/web-components_v3.0.0-alpha.11) + +### Changes + +- update FAST dependencies to latest package versions ([PR #27187](https://github.com/microsoft/fluentui/pull/27187) by chhol@microsoft.com) +- Adds css containment to implemented web components ([PR #27190](https://github.com/microsoft/fluentui/pull/27190) by chhol@microsoft.com) + ## [3.0.0-alpha.10](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.10) Thu, 09 Mar 2023 04:19:45 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index f59477f4bf5f6..4cf0ba0e4aa3b 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.10", + "version": "3.0.0-alpha.11", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From ed4d369066438f0b2f8cf60a9ad6ee1539feda04 Mon Sep 17 00:00:00 2001 From: Ryan Merrill Date: Mon, 27 Mar 2023 11:38:42 -0400 Subject: [PATCH 059/203] Adds Slider as a web component (#27165) * Initial commit of styles and markup for slider * Cleans up some styles and adds Stories for states * More Slider styles and stories * Adds stripes to slider for vertical/horizontal. Deletes SliderLabel as we don't need it * Fixes silly math * Cleans up CSS * Cleans up CSS and Stories for Slider * Initial commit of styles and markup for slider * More Slider styles and stories * Adds stripes to slider for vertical/horizontal. Deletes SliderLabel as we don't need it * Fixes silly math * Fixes some styles on checkmarks * Adds check to see if Step was set * Generates API report * Removes some duplicate CSS and cleans up spec * Adds slider to index.ts and package.json * Addresses initial round of feedback to PR * Renames sizeChanged to stepChanged. Duh. * Adds JSDOC comments * update slider step rate code * Adds export to SliderOrientation * Adds new focus style and fixes overflow visual bug * Fixes build errors * Adds export to SliderOrientation * Adds new focus style and fixes overflow visual bug * Fixes build errors * Runs API report --------- Co-authored-by: Chris Holt --- ...-a3ffbc3c-8b89-4d1c-ba56-3690c7fb06e1.json | 7 + packages/web-components/docs/api-report.md | 33 +++ packages/web-components/package.json | 10 +- packages/web-components/src/index.ts | 1 + .../src/progress-bar/progress-bar.styles.ts | 2 +- .../src/slider-label/slider-label.spec.md | 74 ------- packages/web-components/src/slider/define.ts | 4 + packages/web-components/src/slider/index.ts | 5 + .../src/slider/slider.definition.ts | 18 ++ .../src/slider/slider.options.ts | 17 ++ .../web-components/src/slider/slider.spec.md | 1 - .../src/slider/slider.stories.ts | 80 +++++++ .../src/slider/slider.styles.ts | 202 ++++++++++++++++++ .../src/slider/slider.template.ts | 6 + packages/web-components/src/slider/slider.ts | 76 +++++++ 15 files changed, 457 insertions(+), 79 deletions(-) create mode 100644 change/@fluentui-web-components-a3ffbc3c-8b89-4d1c-ba56-3690c7fb06e1.json delete mode 100644 packages/web-components/src/slider-label/slider-label.spec.md create mode 100644 packages/web-components/src/slider/define.ts create mode 100644 packages/web-components/src/slider/index.ts create mode 100644 packages/web-components/src/slider/slider.definition.ts create mode 100644 packages/web-components/src/slider/slider.options.ts create mode 100644 packages/web-components/src/slider/slider.stories.ts create mode 100644 packages/web-components/src/slider/slider.styles.ts create mode 100644 packages/web-components/src/slider/slider.template.ts create mode 100644 packages/web-components/src/slider/slider.ts diff --git a/change/@fluentui-web-components-a3ffbc3c-8b89-4d1c-ba56-3690c7fb06e1.json b/change/@fluentui-web-components-a3ffbc3c-8b89-4d1c-ba56-3690c7fb06e1.json new file mode 100644 index 0000000000000..19e7d9774d682 --- /dev/null +++ b/change/@fluentui-web-components-a3ffbc3c-8b89-4d1c-ba56-3690c7fb06e1.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Adds Slider as a web component", + "packageName": "@fluentui/web-components", + "email": "ryan@ryanmerrill.net", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/docs/api-report.md b/packages/web-components/docs/api-report.md index 98b44517c142a..f1da965703c52 100644 --- a/packages/web-components/docs/api-report.md +++ b/packages/web-components/docs/api-report.md @@ -16,7 +16,9 @@ import { FASTElement } from '@microsoft/fast-element'; import { FASTElementDefinition } from '@microsoft/fast-element'; import { FASTProgress } from '@microsoft/fast-foundation'; import { FASTProgressRing } from '@microsoft/fast-foundation'; +import { FASTSlider } from '@microsoft/fast-foundation'; import { FASTSwitch } from '@microsoft/fast-foundation'; +import { SliderOrientation } from '@microsoft/fast-foundation'; import { StartEnd } from '@microsoft/fast-foundation'; import { StartEndOptions } from '@microsoft/fast-foundation'; import { StaticallyComposableHTML } from '@microsoft/fast-foundation'; @@ -1603,6 +1605,37 @@ export const shadow8: CSSDesignToken; // @public (undocumented) export const shadow8Brand: CSSDesignToken; +// @public +export class Slider extends FASTSlider { + // (undocumented) + connectedCallback(): void; + // (undocumented) + disconnectedCallback(): void; + // (undocumented) + handleChange(source: any, propertyName: string): void; + size?: SliderSize; +} + +// @public +export const SliderDefinition: FASTElementDefinition; + +export { SliderOrientation } + +// @public +export const SliderSize: { + readonly small: "small"; + readonly medium: "medium"; +}; + +// @public +export type SliderSize = ValuesOf; + +// @public +export const SliderStyles: ElementStyles; + +// @public (undocumented) +export const SliderTemplate: ElementViewTemplate; + // @public (undocumented) export const spacingHorizontalL: CSSDesignToken; diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 4cf0ba0e4aa3b..9682bc4e171ac 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -60,13 +60,17 @@ "types": "./dist/esm/progress-bar/define.d.ts", "default": "./dist/esm/progress-bar/define.js" }, - "./switch": { - "types": "./dist/esm/switch/define.d.ts", - "default": "./dist/esm/switch/define.js" + "./slider": { + "types": "./dist/esm/slider/define.d.ts", + "default": "./dist/esm/slider/define.js" }, "./spinner": { "types": "./dist/esm/spinner/define.d.ts", "default": "./dist/esm/spinner/define.js" + }, + "./switch": { + "types": "./dist/esm/switch/define.d.ts", + "default": "./dist/esm/switch/define.js" } }, "scripts": { diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index 041cf1b698364..8faecf8059979 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -6,6 +6,7 @@ export * from './counter-badge/index.js'; export * from './divider/index.js'; export * from './image/index.js'; export * from './progress-bar/index.js'; +export * from './slider/index.js'; export * from './spinner/index.js'; export * from './switch/index.js'; export * from './text/index.js'; diff --git a/packages/web-components/src/progress-bar/progress-bar.styles.ts b/packages/web-components/src/progress-bar/progress-bar.styles.ts index 2cbab1d9bb757..ef11790da2d58 100644 --- a/packages/web-components/src/progress-bar/progress-bar.styles.ts +++ b/packages/web-components/src/progress-bar/progress-bar.styles.ts @@ -13,7 +13,7 @@ import { colorPaletteRedBackground3, } from '../theme/design-tokens.js'; -/** Text styles +/** ProgressBar styles * @public */ export const styles = css` diff --git a/packages/web-components/src/slider-label/slider-label.spec.md b/packages/web-components/src/slider-label/slider-label.spec.md deleted file mode 100644 index 025c67ccc29b1..0000000000000 --- a/packages/web-components/src/slider-label/slider-label.spec.md +++ /dev/null @@ -1,74 +0,0 @@ -# SliderLabel - -## Description - -A label element intended to be used with the Slider component. Ability to hide the mark or provide a custom label element is baked in. - -## Design Spec - -[Link to Design Spec in Figma](https://www.figma.com/file/IBCBJxEbPKS7CvLHG55Wn9/Slider?node-id=1639%3A12700&t=1cp8zLuAuXd8cLBk-11) - -## Engineering Spec - -### Inputs - -- @attr position | number - The location of the label relative to the minimum and maximum values of the slider -- @attr hide-mark | boolean - Whether or not to hide the mark on the rail - -### Slots - -- label - replaceable with custom DOM element(s) - -### CSS Parts - -- label - how to style the label element by each label mark - -## Accessibility - -- [x] Find the matching component through WCAG's patterns: https://www.w3.org/WAI/ARIA/apg/patterns/ -- [x] Are there any accessibility elements unique to this component? - - No -- [x] Does the component support 400% zoom? - -## Preparation - -- [x] [Find the base FAST Component](https://explore.fast.design/components/) this component will inherit from and document - - [Slider + SliderLabel Spec](https://github.com/microsoft/fast/blob/master/packages/web-components/fast-foundation/src/slider/slider.spec.md) -- [x] [Check the Fluent UI React V9 Component Spec](https://github.com/microsoft/fluentui/tree/master/specs) for differences and document - - [Link to Spec](https://github.com/microsoft/fluentui/blob/master/specs/Slider.md) - - SliderLabel doesn't exist as an independent component in Fluent -- [x] [Fluent UI React V9 Storybook](https://aka.ms/fluentui-storybook) for implementation differences and document - - [Link to Storybook Component](https://master--628d031b55e942004ac95df1.chromatic.com/?path=/docs/components-slider--default) - - Fluent React SliderLabel doesn't allow the display of individual values on each tick mark on rail - - Fluent React Slider only displays value of the labels on the ends of the rail - - SliderLabel doesn't exist as an independent component in Fluent -- [x] [Open GitHub issues related to component](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#find-open-issues-on-github) - - [link to each issue] -- [ ] (Optional) [Draft implementation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#draft-implementation) - - [link to draft implementation, if applicable] -- [ ] [Component Spec authored](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#component-spec) and [reviewed](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#spec-review) - -## Implementation - -- [ ] Initial conformance and unit tests (validate basic functionality) -- [ ] [Initial documentation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#documentation) - - [ ] [Storybook stories](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#storybook-stories) - - [ ] README.md covering basic usage -- [ ] [Component released as unstable](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#unstable-release) from `@fluentui/web-components/unstable` -- [ ] Uses design tokens for styling -- [ ] Renders correctly in High Contrast mode - -## Validation - -- [ ] [Add tests](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#tests) - - [ ] Unit and conformance tests - - [ ] Bundle size fixtures - - [ ] Performance test scenario - - [ ] Accessibility behavior tests - - [ ] Create an issue and run [manual accessibility tests](https://github.com/microsoft/fluentui/wiki/Manual-Accessibility-Review-Checklist): [link to issue] -- [ ] [Validate with partners](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#validation) -- [ ] [Finalize documentation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#finalize-documentation) - - [ ] Review and add any missing storybook stories - - [ ] Finalize migration guide - - [ ] In package.json: Remove the alpha/beta tag from the version number in package.json - - [ ] In package.json: Change beachball's `disallowedChangeTypes` to `"major", "prerelease"` diff --git a/packages/web-components/src/slider/define.ts b/packages/web-components/src/slider/define.ts new file mode 100644 index 0000000000000..ba6e2e8b2c8f6 --- /dev/null +++ b/packages/web-components/src/slider/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './slider.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/slider/index.ts b/packages/web-components/src/slider/index.ts new file mode 100644 index 0000000000000..f48135c8b6264 --- /dev/null +++ b/packages/web-components/src/slider/index.ts @@ -0,0 +1,5 @@ +export * from './slider.js'; +export * from './slider.options.js'; +export { definition as SliderDefinition } from './slider.definition.js'; +export { styles as SliderStyles } from './slider.styles.js'; +export { template as SliderTemplate } from './slider.template.js'; diff --git a/packages/web-components/src/slider/slider.definition.ts b/packages/web-components/src/slider/slider.definition.ts new file mode 100644 index 0000000000000..9d49dfd0e9b63 --- /dev/null +++ b/packages/web-components/src/slider/slider.definition.ts @@ -0,0 +1,18 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Slider } from './slider.js'; +import { styles } from './slider.styles.js'; +import { template } from './slider.template.js'; + +/** + * The Fluent Slider Element. + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = Slider.compose({ + name: `${FluentDesignSystem.prefix}-slider`, + template, + styles, +}); diff --git a/packages/web-components/src/slider/slider.options.ts b/packages/web-components/src/slider/slider.options.ts new file mode 100644 index 0000000000000..22a193caf65cc --- /dev/null +++ b/packages/web-components/src/slider/slider.options.ts @@ -0,0 +1,17 @@ +import { ValuesOf } from '@microsoft/fast-foundation'; +export { SliderOrientation } from '@microsoft/fast-foundation'; + +/** + * SliderSize Constants + * @public + */ +export const SliderSize = { + small: 'small', + medium: 'medium', +} as const; + +/** + * Applies bar height to the slider rail and diameter to the slider thumbs + * @public + */ +export type SliderSize = ValuesOf; diff --git a/packages/web-components/src/slider/slider.spec.md b/packages/web-components/src/slider/slider.spec.md index 5737f68f67d7c..8bcb3441f4b1b 100644 --- a/packages/web-components/src/slider/slider.spec.md +++ b/packages/web-components/src/slider/slider.spec.md @@ -75,7 +75,6 @@ None - no `defaultValue` or `value` attributes, instead only `current-value` that specifies the selected range of the slider - `rail` is in Fluent React; `track` is in FAST Foundation - No value indicators to the left/right of slider in FAST Slider. These should be present in Fluent version. This will be handled through slotting in the the SliderLabel component. - - No default support for the ticks on the slider when `step` is set. This will be handled through slotting in the SliderLabel component. - [x] [Fluent UI React V9 Storybook](https://aka.ms/fluentui-storybook) for implementation differences and document - [Fluent React V9 Slider](https://master--628d031b55e942004ac95df1.chromatic.com/?path=/docs/components-slider--default) - [x] [Open GitHub issues related to component](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#find-open-issues-on-github) diff --git a/packages/web-components/src/slider/slider.stories.ts b/packages/web-components/src/slider/slider.stories.ts new file mode 100644 index 0000000000000..ac16cee62cd28 --- /dev/null +++ b/packages/web-components/src/slider/slider.stories.ts @@ -0,0 +1,80 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../helpers.stories.js'; +import { SliderSize as SliderSetSize } from './slider.options.js'; +import type { Slider as FluentSlider } from './slider.js'; +import './define.js'; + +type SliderStoryArgs = Args & FluentSlider; +type SliderStoryMeta = Meta; + +const storyTemplate = html` + x.disabled} + ?readonly=${x => x.readOnly} + step=${x => x.step} + size=${x => x.size} + min=${x => x.min} + max=${x => x.max} + orientation=${x => x.orientation} + value=${x => x.value} + > +`; + +export default { + title: 'Components/Slider', + args: { + disabled: false, + readOnly: false, + min: 0, + max: 100, + size: SliderSetSize.medium, + orientation: 'horizontal', + }, + argTypes: { + disabled: { control: 'boolean' }, + readOnly: { control: 'boolean' }, + min: { + control: 'number', + defaultValue: 0, + }, + max: { + control: 'number', + defaultValue: 100, + }, + value: { control: 'number', defaultValue: 50 }, + size: { + control: { + type: 'inline-radio', + options: Object.values(SliderSetSize), + }, + }, + orientation: { + control: { + type: 'inline-radio', + options: ['horizontal', 'vertical'], + }, + }, + }, +} as SliderStoryMeta; + +export const Slider = renderComponent(storyTemplate).bind({}); + +export const SliderOrientation = renderComponent(html` + + +`); + +export const SliderSize = renderComponent(html` + + +`); + +export const SliderSteps = renderComponent(html` + +`); + +export const SliderDisabled = renderComponent(html` + + +`); diff --git a/packages/web-components/src/slider/slider.styles.ts b/packages/web-components/src/slider/slider.styles.ts new file mode 100644 index 0000000000000..39017185dad5e --- /dev/null +++ b/packages/web-components/src/slider/slider.styles.ts @@ -0,0 +1,202 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + borderRadiusCircular, + borderRadiusMedium, + borderRadiusSmall, + colorBrandBackground, + colorCompoundBrandBackground, + colorCompoundBrandBackgroundHover, + colorCompoundBrandBackgroundPressed, + colorNeutralBackground1, + colorNeutralBackgroundDisabled, + colorNeutralForegroundDisabled, + colorNeutralStroke1, + colorNeutralStrokeAccessible, + colorNeutralStrokeDisabled, + colorStrokeFocus1, + colorStrokeFocus2, +} from '../theme/design-tokens.js'; + +/** Text styles + * @public + */ +export const styles = css` + ${display('inline-grid')} :host { + --thumb-size: 18px; + --thumb-padding: 3px; + --thumb-translate: calc(var(--thumb-size) * -0.5 + var(--track-width) / 2); + --track-overhang: -2px; + --track-width: 4px; + --fast-slider-height: calc(var(--thumb-size) * 10); + --slider-direction: 90deg; + align-items: center; + box-sizing: border-box; + outline: none; + cursor: pointer; + user-select: none; + border-radius: ${borderRadiusSmall}; + touch-action: pan-y; + min-width: calc(var(--thumb-size) * 1px); + width: 100%; + } + + :host([size='small']) { + --thumb-size: 14px; + --track-width: 2px; + --thumb-padding: 3px; + } + + :host([orientation='vertical']) { + --slider-direction: 0deg; + height: 160px; + min-height: var(--thumb-size); + touch-action: pan-x; + padding: 8px 0; + width: auto; + min-width: auto; + } + + :host([disabled]:hover) { + cursor: initial; + } + + :host(:focus-visible) { + box-shadow: 0 0 0 2pt ${colorStrokeFocus2}; + outline: 1px solid ${colorStrokeFocus1}; + } + + .thumb-cursor:focus { + outline: 0; + } + + /* Thumb Container and Cursor */ + .thumb-container { + position: absolute; + height: var(--thumb-size); + width: var(--thumb-size); + transition: all 0.2s ease; + } + + .thumb-container { + transform: translateX(calc(var(--thumb-size) * 0.5)) translateY(calc(var(--thumb-translate) * -1.5)); + } + + :host([size='small']) .thumb-container { + transform: translateX(calc(var(--thumb-size) * 0.5)) translateY(calc(var(--thumb-translate) * -1.35)); + } + + :host([orientation='vertical']) .thumb-container { + transform: translateX(calc(var(--thumb-translate) * -1.5)) translateY(calc(var(--thumb-size) * -0.5)); + } + + :host([orientation='vertical'][size='small']) .thumb-container { + transform: translateX(calc(var(--thumb-translate) * -1.35)) translateY(calc(var(--thumb-size) * -0.5)); + } + + .thumb-cursor { + height: var(--thumb-size); + width: var(--thumb-size); + background-color: ${colorBrandBackground}; + border-radius: ${borderRadiusCircular}; + box-shadow: inset 0 0 0 var(--thumb-padding) ${colorNeutralBackground1}, 0 0 0 1px ${colorNeutralStroke1}; + } + .thumb-cursor:hover { + background-color: ${colorCompoundBrandBackgroundHover}; + } + .thumb-cursor:active { + background-color: ${colorCompoundBrandBackgroundPressed}; + } + :host([disabled]) .thumb-cursor { + background-color: ${colorNeutralForegroundDisabled}; + box-shadow: inset 0 0 0 var(--thumb-padding) ${colorNeutralBackground1}, 0 0 0 1px ${colorNeutralStrokeDisabled}; + } + + /* Positioning Region */ + .positioning-region { + position: relative; + display: grid; + } + + :host([orientation='horizontal']) .positioning-region { + margin: 0 8px; + grid-template-rows: var(--thumb-size) var(--thumb-size); + } + :host([orientation='vertical']) .positioning-region { + margin: 8px 0; + height: 100%; + grid-template-columns: var(--thumb-size) var(--thumb-size); + } + + /* Track */ + .track { + align-self: start; + position: absolute; + background-color: ${colorNeutralStrokeAccessible}; + border-radius: ${borderRadiusMedium}; + overflow: hidden; + } + + :host([step]) .track::after { + content: ''; + position: absolute; + border-radius: ${borderRadiusMedium}; + width: 100%; + inset: 0 2px; + background-image: repeating-linear-gradient( + var(--slider-direction), + #0000 0%, + #0000 calc(var(--step-rate) - 1px), + ${colorNeutralBackground1} calc(var(--step-rate) - 1px), + ${colorNeutralBackground1} var(--step-rate) + ); + } + + :host([orientation='vertical'][step]) .track::after { + inset: -2px 0; + } + + :host([disabled]) .track { + background-color: ${colorNeutralBackgroundDisabled}; + } + + :host([orientation='horizontal']) .track { + right: var(--track-overhang); + left: var(--track-overhang); + align-self: start; + height: var(--track-width); + grid-row: 2 / auto; + } + + :host([orientation='vertical']) .track { + top: var(--track-overhang); + bottom: var(--track-overhang); + width: var(--track-width); + height: 100%; + grid-column: 2 / auto; + } + .track-start { + background-color: ${colorCompoundBrandBackground}; + position: absolute; + height: 100%; + left: 0; + border-radius: ${borderRadiusMedium}; + } + :host([disabled]) .track-start { + background-color: ${colorNeutralForegroundDisabled}; + } + :host(:hover) .track-start { + background-color: ${colorCompoundBrandBackgroundHover}; + } + :host([disabled]:hover) .track-start { + background-color: ${colorNeutralForegroundDisabled}; + } + .track-start:active { + background-color: ${colorCompoundBrandBackgroundPressed}; + } + :host([orientation='vertical']) .track-start { + height: auto; + width: 100%; + bottom: 0; + } +`; diff --git a/packages/web-components/src/slider/slider.template.ts b/packages/web-components/src/slider/slider.template.ts new file mode 100644 index 0000000000000..4839625537639 --- /dev/null +++ b/packages/web-components/src/slider/slider.template.ts @@ -0,0 +1,6 @@ +import type { ElementViewTemplate } from '@microsoft/fast-element'; +import { FASTSlider, sliderTemplate } from '@microsoft/fast-foundation'; + +export const template: ElementViewTemplate = sliderTemplate({ + thumb: `
`, +}); diff --git a/packages/web-components/src/slider/slider.ts b/packages/web-components/src/slider/slider.ts new file mode 100644 index 0000000000000..e6fa12e20cce9 --- /dev/null +++ b/packages/web-components/src/slider/slider.ts @@ -0,0 +1,76 @@ +import { attr, css, Observable } from '@microsoft/fast-element'; +import type { ElementStyles } from '@microsoft/fast-element'; +import { FASTSlider } from '@microsoft/fast-foundation'; +import type { SliderSize } from './slider.options.js'; + +/** + * The base class used for constructing a fluent-slider custom element + * @public + */ +export class Slider extends FASTSlider { + /** + * The size of the slider + * @public + * @remarks + * HTML Attribute: size + */ + @attr + public size?: SliderSize; + + public handleChange(source: any, propertyName: string): void { + switch (propertyName) { + case 'min': + case 'max': + case 'step': + this.handleStepStyles(); + break; + default: + break; + } + } + + public connectedCallback(): void { + super.connectedCallback(); + + Observable.getNotifier(this).subscribe(this, 'max'); + Observable.getNotifier(this).subscribe(this, 'min'); + Observable.getNotifier(this).subscribe(this, 'step'); + + this.handleStepStyles(); + } + + public disconnectedCallback(): void { + super.disconnectedCallback(); + + Observable.getNotifier(this).unsubscribe(this, 'max'); + Observable.getNotifier(this).unsubscribe(this, 'min'); + Observable.getNotifier(this).unsubscribe(this, 'step'); + } + + private stepStyles?: ElementStyles; + + /** + * Handles changes to step styling based on the step value + * NOTE: This function is not a changed callback, stepStyles is not observable + */ + private handleStepStyles(): void { + if (this.step) { + const totalSteps = (100 / Math.floor((this.max - this.min) / this.step)) as any; + + if (this.stepStyles !== undefined) { + this.$fastController.removeStyles(this.stepStyles); + } + + this.stepStyles = css/**css*/ ` + :host { + --step-rate: ${totalSteps}%; + color: blue; + } + `; + + this.$fastController.addStyles(this.stepStyles); + } else if (this.stepStyles !== undefined) { + this.$fastController.removeStyles(this.stepStyles); + } + } +} From c325360c0581d3a919d9d68c33a9af1fca91a808 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Tue, 28 Mar 2023 04:20:07 +0000 Subject: [PATCH 060/203] applying package updates --- ...ents-a3ffbc3c-8b89-4d1c-ba56-3690c7fb06e1.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) delete mode 100644 change/@fluentui-web-components-a3ffbc3c-8b89-4d1c-ba56-3690c7fb06e1.json diff --git a/change/@fluentui-web-components-a3ffbc3c-8b89-4d1c-ba56-3690c7fb06e1.json b/change/@fluentui-web-components-a3ffbc3c-8b89-4d1c-ba56-3690c7fb06e1.json deleted file mode 100644 index 19e7d9774d682..0000000000000 --- a/change/@fluentui-web-components-a3ffbc3c-8b89-4d1c-ba56-3690c7fb06e1.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "Adds Slider as a web component", - "packageName": "@fluentui/web-components", - "email": "ryan@ryanmerrill.net", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index c8f84f428aaa3..7c60231de5493 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Tue, 28 Mar 2023 04:20:01 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.12", + "version": "3.0.0-alpha.12", + "comments": { + "prerelease": [ + { + "author": "ryan@ryanmerrill.net", + "package": "@fluentui/web-components", + "commit": "d63779409cf8b7565b415fdac51e09cf4dbc6e08", + "comment": "Adds Slider as a web component" + } + ] + } + }, { "date": "Tue, 14 Mar 2023 04:21:22 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.11", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index 317265b3bed6d..eae59bb49faf0 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Tue, 14 Mar 2023 04:21:22 GMT and should not be manually modified. +This log was last generated on Tue, 28 Mar 2023 04:20:01 GMT and should not be manually modified. +## [3.0.0-alpha.12](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.12) + +Tue, 28 Mar 2023 04:20:01 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.11..@fluentui/web-components_v3.0.0-alpha.12) + +### Changes + +- Adds Slider as a web component ([PR #27165](https://github.com/microsoft/fluentui/pull/27165) by ryan@ryanmerrill.net) + ## [3.0.0-alpha.11](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.11) Tue, 14 Mar 2023 04:21:22 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 9682bc4e171ac..795d513d2fa76 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.11", + "version": "3.0.0-alpha.12", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 75f0d6d06f6a8c7196bcb2e47a2029646aa0f8d8 Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Thu, 30 Mar 2023 16:00:37 -0700 Subject: [PATCH 061/203] update fast-elment to 2.0.0-beta.23 and fast-foundation to 3.0.0-alpha.27 (#27392) --- ...s-9d8d0650-6506-4332-97ba-4f96836470e2.json | 7 +++++++ packages/web-components/package.json | 4 ++-- yarn.lock | 18 +++++++++--------- 3 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 change/@fluentui-web-components-9d8d0650-6506-4332-97ba-4f96836470e2.json diff --git a/change/@fluentui-web-components-9d8d0650-6506-4332-97ba-4f96836470e2.json b/change/@fluentui-web-components-9d8d0650-6506-4332-97ba-4f96836470e2.json new file mode 100644 index 0000000000000..24938dd1bd475 --- /dev/null +++ b/change/@fluentui-web-components-9d8d0650-6506-4332-97ba-4f96836470e2.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "update fast-element and fast-foundation dependencies", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 795d513d2fa76..6c2df52c07236 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -129,8 +129,8 @@ "typescript": "4.7.4" }, "dependencies": { - "@microsoft/fast-element": "^2.0.0-beta.22", - "@microsoft/fast-foundation": "^3.0.0-alpha.26", + "@microsoft/fast-element": "^2.0.0-beta.23", + "@microsoft/fast-foundation": "^3.0.0-alpha.27", "@microsoft/fast-web-utilities": "^6.0.0", "@fluentui/tokens": "1.0.0-alpha.2", "tslib": "^2.1.0" diff --git a/yarn.lock b/yarn.lock index 34b7b512edef7..a6f6b075240d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2657,18 +2657,18 @@ eslint-plugin-react "7.24.0" eslint-plugin-security "1.4.0" -"@microsoft/fast-element@^2.0.0-beta.22": - version "2.0.0-beta.22" - resolved "https://registry.yarnpkg.com/@microsoft/fast-element/-/fast-element-2.0.0-beta.22.tgz#e8a508544b2af9db387e9e728d0de1fb9b8f1a12" - integrity sha512-uyNiiTp59BN0uiRE5f2avwTR5vNoPavTFvPQ+v8UcWgL4Zi206dTfIOEH/hR0eeY8Jw3w0C6FHNSc/ehetkzWg== +"@microsoft/fast-element@2.0.0-beta.23", "@microsoft/fast-element@^2.0.0-beta.23": + version "2.0.0-beta.23" + resolved "https://registry.yarnpkg.com/@microsoft/fast-element/-/fast-element-2.0.0-beta.23.tgz#08cc4b40f9d2b418a27727d2604635c46c2b123c" + integrity sha512-ZNrWz+qY6kYSiiy6TdMV9p94QbxNILWuFgDndf24/is+aB+IemYwqLVPUKzTb8tX/zUMQz8aOtJ06/qvYbIdAQ== -"@microsoft/fast-foundation@^3.0.0-alpha.26": - version "3.0.0-alpha.26" - resolved "https://registry.yarnpkg.com/@microsoft/fast-foundation/-/fast-foundation-3.0.0-alpha.26.tgz#eb21b5f9ee5d4dccf17da1e709a78775ce1278ad" - integrity sha512-78UJIbS20lCQ9rOyUZMwjXIeEDFBjJZM0DJ7bYUIXgx7JDXygYi8RxnmCFiO0h9XABubiuOJrGDJtqro5sgS7g== +"@microsoft/fast-foundation@^3.0.0-alpha.27": + version "3.0.0-alpha.27" + resolved "https://registry.yarnpkg.com/@microsoft/fast-foundation/-/fast-foundation-3.0.0-alpha.27.tgz#cb91af92fb231710f7c346b11db7afe241ff8bb4" + integrity sha512-tYDrHWMDNpi3+3RaRZ79T+6VQubYSxxutxELD88WXPEYiafjgext4AH9MvR+2pUpdfrNPcJLyuEQKVvcx6oWuQ== dependencies: "@floating-ui/dom" "^1.0.3" - "@microsoft/fast-element" "^2.0.0-beta.22" + "@microsoft/fast-element" "2.0.0-beta.23" "@microsoft/fast-web-utilities" "^6.0.0" tabbable "^5.2.0" tslib "^2.4.0" From 7dda763c61c557753ced5bcf2d5f9d08e45600ed Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Thu, 30 Mar 2023 18:21:34 -0700 Subject: [PATCH 062/203] feat(button): add button to web components v3 (#27278) * add button as a new web component * change files * add package export * add icon attr, fixup disabled styles * update color => fill * add disabled focusable click handling * move to attribute syntax for aria-disabled * remove icon attribute in favor of min-height to accommodate icons * use long form for padding to ensure we catch browser defaults * add basic readme with deltas --- ...-be1b97fa-2097-4adc-ad03-f84e0ac0b1b1.json | 7 + packages/web-components/package.json | 4 + packages/web-components/src/button/README.md | 48 +++ .../src/button/button.definition.ts | 21 ++ .../src/button/button.options.ts | 53 +++ .../src/button/button.stories.ts | 208 ++++++++++++ .../src/button/button.styles.ts | 308 ++++++++++++++++++ .../src/button/button.template.ts | 9 + packages/web-components/src/button/button.ts | 92 ++++++ packages/web-components/src/button/define.ts | 4 + packages/web-components/src/button/index.ts | 5 + packages/web-components/src/index.ts | 1 + 12 files changed, 760 insertions(+) create mode 100644 change/@fluentui-web-components-be1b97fa-2097-4adc-ad03-f84e0ac0b1b1.json create mode 100644 packages/web-components/src/button/README.md create mode 100644 packages/web-components/src/button/button.definition.ts create mode 100644 packages/web-components/src/button/button.options.ts create mode 100644 packages/web-components/src/button/button.stories.ts create mode 100644 packages/web-components/src/button/button.styles.ts create mode 100644 packages/web-components/src/button/button.template.ts create mode 100644 packages/web-components/src/button/button.ts create mode 100644 packages/web-components/src/button/define.ts create mode 100644 packages/web-components/src/button/index.ts diff --git a/change/@fluentui-web-components-be1b97fa-2097-4adc-ad03-f84e0ac0b1b1.json b/change/@fluentui-web-components-be1b97fa-2097-4adc-ad03-f84e0ac0b1b1.json new file mode 100644 index 0000000000000..d5ddae11444d7 --- /dev/null +++ b/change/@fluentui-web-components-be1b97fa-2097-4adc-ad03-f84e0ac0b1b1.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat(button): add button web component", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 6c2df52c07236..8455cc240d8e9 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -40,6 +40,10 @@ "types": "./dist/esm/badge/define.d.ts", "default": "./dist/esm/badge/define.js" }, + "./button": { + "types": "./dist/esm/button/define.d.ts", + "default": "./dist/esm/button/define.js" + }, "./counter-badge": { "types": "./dist/esm/counter-badge/define.d.ts", "default": "./dist/esm/counter-badge/define.js" diff --git a/packages/web-components/src/button/README.md b/packages/web-components/src/button/README.md new file mode 100644 index 0000000000000..bbcd0815837fd --- /dev/null +++ b/packages/web-components/src/button/README.md @@ -0,0 +1,48 @@ +# Button + +The `Button` component allows users to commit a change or trigger an action via a single click or tap and is often found inside forms, dialogs, panels and/or pages. + +## **Design Spec** + +[Link to Button in Figma](https://www.figma.com/file/Nj9EBBvOZmS11zKNJfilVR/Button?node-id=1723%3A380&t=PNVwuI4rLXjxAFNJ-1) + +
+ +## **Engineering Spec** + +Fluent WC3 Button has feature parity with the Fluent UI React 9 Button implementation but not direct parity. + +
+ +## Class: `Button` + +
+ +### **Component Name** + +`` + +
+ +## **Preparation** + +
+ +### **Fluent Web Component v3 v.s Fluent React 9** + +
+ +**Component and Slot Mapping** + +| Fluent UI React 9 | Fluent Web Components 3 | +| ----------------- | ----------------------- | +| ` + `; +} + +/** + * The template for the Button component. + * @public + */ +export const template: ElementViewTemplate = buttonTemplate(); diff --git a/packages/web-components/src/compound-button/compound-button.ts b/packages/web-components/src/compound-button/compound-button.ts new file mode 100644 index 0000000000000..6efd06e50ef06 --- /dev/null +++ b/packages/web-components/src/compound-button/compound-button.ts @@ -0,0 +1,7 @@ +import { Button } from '../button/button.js'; + +/** + * The base class used for constructing a fluent-compound-button custom element + * @public + */ +export class CompoundButton extends Button {} diff --git a/packages/web-components/src/compound-button/define.ts b/packages/web-components/src/compound-button/define.ts new file mode 100644 index 0000000000000..c87e2bd253047 --- /dev/null +++ b/packages/web-components/src/compound-button/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './compound-button.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/compound-button/index.ts b/packages/web-components/src/compound-button/index.ts new file mode 100644 index 0000000000000..e4e0bc601f76e --- /dev/null +++ b/packages/web-components/src/compound-button/index.ts @@ -0,0 +1,5 @@ +export * from './compound-button.js'; +export * from './compound-button.options.js'; +export { template as CompoundButtonTemplate } from './compound-button.template.js'; +export { styles as CompoundButtonStyles } from './compound-button.styles.js'; +export { definition as CompoundButtonDefinition } from './compound-button.definition.js'; diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index 59cea6af59bb2..3d5135434b822 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -3,6 +3,7 @@ export * from './accordion-item/index.js'; export * from './avatar/index.js'; export * from './badge/index.js'; export * from './button/index.js'; +export * from './compound-button/index.js'; export * from './counter-badge/index.js'; export * from './divider/index.js'; export * from './image/index.js'; From 837c3ca19c8491880a7a0e29a30cf0adc6c7b2b5 Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Tue, 11 Apr 2023 11:15:59 -0700 Subject: [PATCH 075/203] add anchor button as a new component to web components v3 (#27395) * add anchor as a new component to support anchor-button scenario * dont forget managing anchor disabled * update naming to anchor button * Update change/@fluentui-web-components-b7e6d7ad-6aac-4ccb-b7ee-97424d76f9a2.json --- ...-b7e6d7ad-6aac-4ccb-b7ee-97424d76f9a2.json | 7 + packages/web-components/package.json | 4 + .../anchor-button/anchor-button.definition.ts | 21 ++ .../anchor-button/anchor-button.options.ts | 40 ++++ .../anchor-button/anchor-button.stories.ts | 214 ++++++++++++++++++ .../src/anchor-button/anchor-button.styles.ts | 11 + .../anchor-button/anchor-button.template.ts | 9 + .../src/anchor-button/anchor-button.ts | 111 +++++++++ .../src/anchor-button/define.ts | 4 + .../web-components/src/anchor-button/index.ts | 4 + packages/web-components/src/index.ts | 1 + 11 files changed, 426 insertions(+) create mode 100644 change/@fluentui-web-components-b7e6d7ad-6aac-4ccb-b7ee-97424d76f9a2.json create mode 100644 packages/web-components/src/anchor-button/anchor-button.definition.ts create mode 100644 packages/web-components/src/anchor-button/anchor-button.options.ts create mode 100644 packages/web-components/src/anchor-button/anchor-button.stories.ts create mode 100644 packages/web-components/src/anchor-button/anchor-button.styles.ts create mode 100644 packages/web-components/src/anchor-button/anchor-button.template.ts create mode 100644 packages/web-components/src/anchor-button/anchor-button.ts create mode 100644 packages/web-components/src/anchor-button/define.ts create mode 100644 packages/web-components/src/anchor-button/index.ts diff --git a/change/@fluentui-web-components-b7e6d7ad-6aac-4ccb-b7ee-97424d76f9a2.json b/change/@fluentui-web-components-b7e6d7ad-6aac-4ccb-b7ee-97424d76f9a2.json new file mode 100644 index 0000000000000..d7029605e6490 --- /dev/null +++ b/change/@fluentui-web-components-b7e6d7ad-6aac-4ccb-b7ee-97424d76f9a2.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat(anchor-button): add anchor button to web components", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index cc90f8b8fed2a..200b0feced2d4 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -32,6 +32,10 @@ "types": "./dist/esm/accordion-item/define.d.ts", "default": "./dist/esm/accordion-item/define.js" }, + "./anchor-button": { + "types": "./dist/esm/anchor-button/define.d.ts", + "default": "./dist/esm/anchor-button/define.js" + }, "./avatar": { "types": "./dist/esm/avatar/define.d.ts", "default": "./dist/esm/avatar/define.js" diff --git a/packages/web-components/src/anchor-button/anchor-button.definition.ts b/packages/web-components/src/anchor-button/anchor-button.definition.ts new file mode 100644 index 0000000000000..9a76a726216de --- /dev/null +++ b/packages/web-components/src/anchor-button/anchor-button.definition.ts @@ -0,0 +1,21 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { AnchorButton } from './anchor-button.js'; +import { styles } from './anchor-button.styles.js'; +import { template } from './anchor-button.template.js'; + +/** + * The Fluent Anchor Button Element. Implements {@link @microsoft/fast-foundation#Anchor }, + * {@link @microsoft/fast-foundation#anchorTemplate} + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = AnchorButton.compose({ + name: `${FluentDesignSystem.prefix}-anchor-button`, + template, + styles, + shadowOptions: { + delegatesFocus: true, + }, +}); diff --git a/packages/web-components/src/anchor-button/anchor-button.options.ts b/packages/web-components/src/anchor-button/anchor-button.options.ts new file mode 100644 index 0000000000000..fe3388760cf76 --- /dev/null +++ b/packages/web-components/src/anchor-button/anchor-button.options.ts @@ -0,0 +1,40 @@ +import { AnchorOptions, ValuesOf } from '@microsoft/fast-foundation'; +import { ButtonAppearance, ButtonShape, ButtonSize } from '../button/button.options.js'; + +/** + * Anchor Button Appearance constants + * @public + */ +export const AnchorButtonAppearance = ButtonAppearance; + +/** + * An Anchor Button can be secondary, primary, outline, subtle, transparent + * @public + */ +export type AnchorButtonAppearance = ValuesOf; + +/** + * An Anchor Button can be square, circular or rounded. + * @public + */ +export const AnchorButtonShape = ButtonShape; + +/** + * An Anchor Button can be square, circular or rounded + * @public + */ +export type AnchorButtonShape = ValuesOf; + +/** + * An Anchor Button can be a size of small, medium or large. + * @public + */ +export const AnchorButtonSize = ButtonSize; + +/** + * An Anchor Button can be on of several preset sizes. + * @public + */ +export type AnchorButtonSize = ValuesOf; + +export { AnchorOptions as AnchorButtonOptions }; diff --git a/packages/web-components/src/anchor-button/anchor-button.stories.ts b/packages/web-components/src/anchor-button/anchor-button.stories.ts new file mode 100644 index 0000000000000..bd5d7e359d0d8 --- /dev/null +++ b/packages/web-components/src/anchor-button/anchor-button.stories.ts @@ -0,0 +1,214 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../helpers.stories.js'; +import type { AnchorButton as FluentAnchorButton } from './anchor-button.js'; +import { AnchorButtonAppearance, AnchorButtonShape, AnchorButtonSize } from './anchor-button.options.js'; +import './define.js'; + +type AnchorButtonStoryArgs = Args & FluentAnchorButton; +type AnchorButtonStoryMeta = Meta; + +const storyTemplate = html` + + ${x => x.content} + +`; + +export default { + title: 'Components/Button/Anchor', + args: { + content: 'Anchor', + href: '#', + disabled: false, + disabledFocusable: false, + }, + argTypes: { + appearance: { + options: Object.values(AnchorButtonAppearance), + control: { + type: 'select', + }, + }, + shape: { + options: Object.values(AnchorButtonShape), + control: { + type: 'select', + }, + }, + size: { + options: Object.values(AnchorButtonSize), + control: { + type: 'select', + }, + }, + disabled: { + control: 'boolean', + table: { + type: { + summary: 'Sets the disabled state of the component', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + disabledFocusable: { + control: 'boolean', + table: { + type: { + summary: 'The component is disabled but still focusable', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + href: { + control: 'text', + }, + content: { + control: 'Anchor text', + }, + }, +} as AnchorButtonStoryMeta; + +export const AnchorButton = renderComponent(storyTemplate).bind({}); + +export const Appearance = renderComponent(html` + Default + Primary + Outline + Subtle + Transparent +`); + +export const Shape = renderComponent(html` + Rounded + Circular + Square +`); + +export const Size = renderComponent(html` + Small + Small with calendar icon + + Medium + Medium with calendar icon + + Large + Large with calendar icon + +`); + +export const Disabled = renderComponent(html` + Enabled state + Disabled state + Disabled focusable state + Enabled state + Disabled state + Disabled focusable state +`); + +export const WithLongText = renderComponent(html` + + Short text + Long text wraps after it hits the max width of the component +`); diff --git a/packages/web-components/src/anchor-button/anchor-button.styles.ts b/packages/web-components/src/anchor-button/anchor-button.styles.ts new file mode 100644 index 0000000000000..1ed8be89a664b --- /dev/null +++ b/packages/web-components/src/anchor-button/anchor-button.styles.ts @@ -0,0 +1,11 @@ +import { css } from '@microsoft/fast-element'; +import { styles as ButtonStyles } from '../button/button.styles.js'; + +// Need to support icon hover styles +export const styles = css` + ${ButtonStyles} + + .content { + text-align: center; + } +`; diff --git a/packages/web-components/src/anchor-button/anchor-button.template.ts b/packages/web-components/src/anchor-button/anchor-button.template.ts new file mode 100644 index 0000000000000..cc61c8363faac --- /dev/null +++ b/packages/web-components/src/anchor-button/anchor-button.template.ts @@ -0,0 +1,9 @@ +import { ElementViewTemplate } from '@microsoft/fast-element'; +import { anchorTemplate } from '@microsoft/fast-foundation'; +import type { AnchorButton } from './anchor-button.js'; + +/** + * The template for the Button component. + * @public + */ +export const template: ElementViewTemplate = anchorTemplate(); diff --git a/packages/web-components/src/anchor-button/anchor-button.ts b/packages/web-components/src/anchor-button/anchor-button.ts new file mode 100644 index 0000000000000..2a10a7446ad09 --- /dev/null +++ b/packages/web-components/src/anchor-button/anchor-button.ts @@ -0,0 +1,111 @@ +import { attr } from '@microsoft/fast-element'; +import { FASTAnchor } from '@microsoft/fast-foundation'; +import { AnchorButtonAppearance, AnchorButtonShape, AnchorButtonSize } from './anchor-button.options.js'; + +/** + * The base class used for constructing a fluent-anchor-button custom element + * @public + */ +export class AnchorButton extends FASTAnchor { + /** + * The appearance the anchor button should have. + * + * @public + * @remarks + * HTML Attribute: appearance + */ + @attr + public appearance?: AnchorButtonAppearance | undefined; + + /** + * The shape the anchor button should have. + * + * @public + * @remarks + * HTML Attribute: shape + */ + @attr + public shape?: AnchorButtonShape | undefined; + + /** + * The size the anchor button should have. + * + * @public + * @remarks + * HTML Attribute: size + */ + @attr + public size?: AnchorButtonSize; + + /** + * The anchor button has an icon only, no text content + * + * @public + * @remarks + * HTML Attribute: icon-only + */ + @attr({ attribute: 'icon-only', mode: 'boolean' }) + public iconOnly: boolean = false; + + /** + * The anchor button is disabled + * + * @public + * @remarks + * HTML Attribute: disabled-focusable + */ + @attr({ mode: 'boolean' }) + public disabled?: boolean = false; + protected disabledChanged(prev: boolean, next: boolean): void { + if (this.disabled) { + ((this as unknown) as HTMLElement).setAttribute('aria-disabled', 'true'); + ((this as unknown) as HTMLElement).setAttribute('tabindex', '-1'); + } else { + ((this as unknown) as HTMLElement).removeAttribute('aria-disabled'); + ((this as unknown) as HTMLElement).removeAttribute('tabindex'); + } + } + + /** + * The anchor button is disabled but focusable + * + * @public + * @remarks + * HTML Attribute: disabled-focusable + */ + @attr({ attribute: 'disabled-focusable', mode: 'boolean' }) + public disabledFocusable?: boolean = false; + protected disabledFocusableChanged(prev: boolean, next: boolean): void { + if (!this.$fastController.isConnected) { + return; + } + + if (this.disabledFocusable) { + ((this as unknown) as HTMLElement).setAttribute('aria-disabled', 'true'); + } else { + ((this as unknown) as HTMLElement).removeAttribute('aria-disabled'); + } + } + + /** + * Prevents disabledFocusable click events + */ + private handleDisabledFocusableClick = (e: MouseEvent): void => { + if ((e && this.disabled) || this.disabledFocusable) { + e.stopImmediatePropagation(); + return; + } + }; + + public connectedCallback(): void { + super.connectedCallback(); + + ((this as unknown) as HTMLElement).addEventListener('click', this.handleDisabledFocusableClick); + } + + public disconnectedCallback(): void { + super.disconnectedCallback(); + + ((this as unknown) as HTMLElement).removeEventListener('click', this.handleDisabledFocusableClick); + } +} diff --git a/packages/web-components/src/anchor-button/define.ts b/packages/web-components/src/anchor-button/define.ts new file mode 100644 index 0000000000000..6319bafd77867 --- /dev/null +++ b/packages/web-components/src/anchor-button/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './anchor-button.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/anchor-button/index.ts b/packages/web-components/src/anchor-button/index.ts new file mode 100644 index 0000000000000..0623781e9ad72 --- /dev/null +++ b/packages/web-components/src/anchor-button/index.ts @@ -0,0 +1,4 @@ +export * from './anchor-button.js'; +export * from './anchor-button.options.js'; +export { template as AnchorButtonTemplate } from './anchor-button.template.js'; +export { definition as AnchorButtonDefinition } from './anchor-button.definition.js'; diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index 3d5135434b822..5f9a056cf2269 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -1,5 +1,6 @@ export * from './accordion/index.js'; export * from './accordion-item/index.js'; +export * from './anchor-button/index.js'; export * from './avatar/index.js'; export * from './badge/index.js'; export * from './button/index.js'; From 2ae63de044db0a8aad442cb5d2faff6d69535ade Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Tue, 11 Apr 2023 15:12:08 -0700 Subject: [PATCH 076/203] add toggle button as new v3 web component (#27405) * add toggle button as a new web component * address ts and lint errors * remove unnecessary css reassignment * remove unnecessary icon attr from stories * add checked stories and fix subtle appearance --- ...-23fff9de-b107-430a-b67b-d0d5f26212e1.json | 7 + packages/web-components/package.json | 4 + packages/web-components/src/index.ts | 1 + .../src/toggle-button/define.ts | 4 + .../web-components/src/toggle-button/index.ts | 5 + .../toggle-button/toggle-button.definition.ts | 21 ++ .../toggle-button/toggle-button.options.ts | 39 +++ .../toggle-button/toggle-button.stories.ts | 229 ++++++++++++++++++ .../src/toggle-button/toggle-button.styles.ts | 108 +++++++++ .../toggle-button/toggle-button.template.ts | 9 + .../src/toggle-button/toggle-button.ts | 104 ++++++++ 11 files changed, 531 insertions(+) create mode 100644 change/@fluentui-web-components-23fff9de-b107-430a-b67b-d0d5f26212e1.json create mode 100644 packages/web-components/src/toggle-button/define.ts create mode 100644 packages/web-components/src/toggle-button/index.ts create mode 100644 packages/web-components/src/toggle-button/toggle-button.definition.ts create mode 100644 packages/web-components/src/toggle-button/toggle-button.options.ts create mode 100644 packages/web-components/src/toggle-button/toggle-button.stories.ts create mode 100644 packages/web-components/src/toggle-button/toggle-button.styles.ts create mode 100644 packages/web-components/src/toggle-button/toggle-button.template.ts create mode 100644 packages/web-components/src/toggle-button/toggle-button.ts diff --git a/change/@fluentui-web-components-23fff9de-b107-430a-b67b-d0d5f26212e1.json b/change/@fluentui-web-components-23fff9de-b107-430a-b67b-d0d5f26212e1.json new file mode 100644 index 0000000000000..4fe7cd7d58f80 --- /dev/null +++ b/change/@fluentui-web-components-23fff9de-b107-430a-b67b-d0d5f26212e1.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat(toggle-button): add toggle button web component", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 200b0feced2d4..3474005383b15 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -103,6 +103,10 @@ "./text": { "types": "./dist/esm/text/define.d.ts", "default": "./dist/esm/text/define.js" + }, + "./toggle-button": { + "types": "./dist/esm/toggle-button/define.d.ts", + "default": "./dist/esm/toggle-button/define.js" } }, "scripts": { diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index 5f9a056cf2269..b006d274be2b7 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -18,5 +18,6 @@ export * from './tabs/index.js'; export * from './tab/index.js'; export * from './tab-panel/index.js'; export * from './text/index.js'; +export * from './toggle-button/index.js'; export * from './theme/index.js'; diff --git a/packages/web-components/src/toggle-button/define.ts b/packages/web-components/src/toggle-button/define.ts new file mode 100644 index 0000000000000..f254548a875b0 --- /dev/null +++ b/packages/web-components/src/toggle-button/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './toggle-button.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/toggle-button/index.ts b/packages/web-components/src/toggle-button/index.ts new file mode 100644 index 0000000000000..004c061cfd624 --- /dev/null +++ b/packages/web-components/src/toggle-button/index.ts @@ -0,0 +1,5 @@ +export * from './toggle-button.js'; +export * from './toggle-button.options.js'; +export { template as ToggleButtonTemplate } from './toggle-button.template.js'; +export { styles as ToggleButtonStyles } from './toggle-button.styles.js'; +export { definition as ToggleButtonDefinition } from './toggle-button.definition.js'; diff --git a/packages/web-components/src/toggle-button/toggle-button.definition.ts b/packages/web-components/src/toggle-button/toggle-button.definition.ts new file mode 100644 index 0000000000000..ad1d8e5026b1d --- /dev/null +++ b/packages/web-components/src/toggle-button/toggle-button.definition.ts @@ -0,0 +1,21 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { ToggleButton } from './toggle-button.js'; +import { styles } from './toggle-button.styles.js'; +import { template } from './toggle-button.template.js'; + +/** + * The Fluent Toggle Button Element. Implements {@link @microsoft/fast-foundation#Button }, + * {@link @microsoft/fast-foundation#buttonTemplate} + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = ToggleButton.compose({ + name: `${FluentDesignSystem.prefix}-toggle-button`, + template, + styles, + shadowOptions: { + delegatesFocus: true, + }, +}); diff --git a/packages/web-components/src/toggle-button/toggle-button.options.ts b/packages/web-components/src/toggle-button/toggle-button.options.ts new file mode 100644 index 0000000000000..0b0c4f3004459 --- /dev/null +++ b/packages/web-components/src/toggle-button/toggle-button.options.ts @@ -0,0 +1,39 @@ +import { ButtonOptions, ValuesOf } from '@microsoft/fast-foundation'; +import { ButtonAppearance, ButtonShape, ButtonSize } from '../button/button.options.js'; + +/** + * Toggle Button Appearance constants + * @public + */ +export const ToggleButtonAppearance = ButtonAppearance; +/** + * A Toggle Button can be secondary, primary, outline, subtle, transparent + * @public + */ +export type ToggleButtonAppearance = ValuesOf; + +/** + * A Toggle Button can be square, circular or rounded. + * @public + */ +export const ToggleButtonShape = ButtonShape; + +/** + * A Toggle Button can be square, circular or rounded + * @public + */ +export type ToggleButtonShape = ValuesOf; + +/** + * A Toggle Button can be a size of small, medium or large. + * @public + */ +export const ToggleButtonSize = ButtonSize; + +/** + * A Toggle Button can be on of several preset sizes. + * @public + */ +export type ToggleButtonSize = ValuesOf; + +export { ButtonOptions as ToggleButtonOptions }; diff --git a/packages/web-components/src/toggle-button/toggle-button.stories.ts b/packages/web-components/src/toggle-button/toggle-button.stories.ts new file mode 100644 index 0000000000000..29c858d1948af --- /dev/null +++ b/packages/web-components/src/toggle-button/toggle-button.stories.ts @@ -0,0 +1,229 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../helpers.stories.js'; +import type { ToggleButton as FluentToggleButton } from './toggle-button.js'; +import { ToggleButtonAppearance, ToggleButtonShape, ToggleButtonSize } from './toggle-button.options.js'; +import './define.js'; + +type ToggleButtonStoryArgs = Args & FluentToggleButton; +type ToggleButtonStoryMeta = Meta; + +const storyTemplate = html` + + ${x => x.content} + +`; + +export default { + title: 'Components/Button/Toggle Button', + args: { + content: 'Button', + disabled: false, + disabledFocusable: false, + }, + argTypes: { + appearance: { + options: Object.values(ToggleButtonAppearance), + control: { + type: 'select', + }, + }, + shape: { + options: Object.values(ToggleButtonShape), + control: { + type: 'select', + }, + }, + size: { + options: Object.values(ToggleButtonSize), + control: { + type: 'select', + }, + }, + checked: { + control: 'boolean', + table: { + type: { + summary: 'Sets the checked state of the component', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + disabled: { + control: 'boolean', + table: { + type: { + summary: 'Sets the disabled state of the component', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + disabledFocusable: { + control: 'boolean', + table: { + type: { + summary: 'The component is disabled but still focusable', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + content: { + control: 'Button text', + }, + }, +} as ToggleButtonStoryMeta; + +export const Button = renderComponent(storyTemplate).bind({}); + +export const Appearance = renderComponent(html` + Default + Primary + Outline + Subtle + Transparent +`); + +export const Checked = renderComponent(html` + Default checked + Primary checked + Outline checked + Subtle checked + Transparent checked +`); + +export const Shape = renderComponent(html` + Rounded + Circular + Square +`); + +export const Size = renderComponent(html` + Small + Small with calendar icon + + Medium + Medium with calendar icon + + Large + Large with calendar icon + +`); + +export const Disabled = renderComponent(html` + Enabled state + Disabled state + Disabled focusable state + Enabled state + Disabled state + Disabled focusable state +`); + +export const WithLongText = renderComponent(html` + + Short text + Long text wraps after it hits the max width of the component +`); diff --git a/packages/web-components/src/toggle-button/toggle-button.styles.ts b/packages/web-components/src/toggle-button/toggle-button.styles.ts new file mode 100644 index 0000000000000..ff067f5fb99ba --- /dev/null +++ b/packages/web-components/src/toggle-button/toggle-button.styles.ts @@ -0,0 +1,108 @@ +import { css } from '@microsoft/fast-element'; +import { styles as ButtonStyles } from '../button/button.styles.js'; +import { + colorBrandBackgroundHover, + colorBrandBackgroundPressed, + colorBrandBackgroundSelected, + colorNeutralBackground1Hover, + colorNeutralBackground1Pressed, + colorNeutralBackground1Selected, + colorNeutralForeground1, + colorNeutralForeground2BrandHover, + colorNeutralForeground2BrandPressed, + colorNeutralForeground2BrandSelected, + colorNeutralForeground2Hover, + colorNeutralForeground2Pressed, + colorNeutralForeground2Selected, + colorNeutralForegroundOnBrand, + colorNeutralStroke1, + colorNeutralStroke1Hover, + colorNeutralStroke1Pressed, + colorSubtleBackgroundHover, + colorSubtleBackgroundPressed, + colorSubtleBackgroundSelected, + colorTransparentBackgroundHover, + colorTransparentBackgroundPressed, + colorTransparentBackgroundSelected, + strokeWidthThin, +} from '../theme/design-tokens.js'; + +// Need to support icon hover styles +export const styles = css` + ${ButtonStyles} + + :host([aria-pressed="true"]) .control { + border-color: ${colorNeutralStroke1}; + background-color: ${colorNeutralBackground1Selected}; + color: ${colorNeutralForeground1}; + border-width: ${strokeWidthThin}; + } + + :host([aria-pressed='true']:hover) .control { + border-color: ${colorNeutralStroke1Hover}; + background-color: ${colorNeutralBackground1Hover}; + } + + :host([aria-pressed='true']:active) .control { + border-color: ${colorNeutralStroke1Pressed}; + background-color: ${colorNeutralBackground1Pressed}; + } + + :host([aria-pressed='true'][appearance='primary']) .control { + border-color: transparent; + background-color: ${colorBrandBackgroundSelected}; + color: ${colorNeutralForegroundOnBrand}; + } + + :host([aria-pressed='true'][appearance='primary']:hover) .control { + background-color: ${colorBrandBackgroundHover}; + } + + :host([aria-pressed='true'][appearance='primary']:active) .control { + background-color: ${colorBrandBackgroundPressed}; + } + + :host([aria-pressed='true'][appearance='subtle']) .control { + border-color: transparent; + background-color: ${colorSubtleBackgroundSelected}; + color: ${colorNeutralForeground2Selected}; + } + + :host([aria-pressed='true'][appearance='subtle']:hover) .control { + background-color: ${colorSubtleBackgroundHover}; + color: ${colorNeutralForeground2Hover}; + } + + :host([aria-pressed='true'][appearance='subtle']:active) .control { + background-color: ${colorSubtleBackgroundPressed}; + color: ${colorNeutralForeground2Pressed}; + } + + :host([aria-pressed='true'][appearance='outline']) .control, + :host([aria-pressed='true'][appearance='transparent']) .control { + background-color: ${colorTransparentBackgroundSelected}; + } + + :host([aria-pressed='true'][appearance='outline']:hover) .control, + :host([aria-pressed='true'][appearance='transparent']:hover) .control { + background-color: ${colorTransparentBackgroundHover}; + } + + :host([aria-pressed='true'][appearance='outline']:active) .control, + :host([aria-pressed='true'][appearance='transparent']:active) .control { + background-color: ${colorTransparentBackgroundPressed}; + } + + :host([aria-pressed='true'][appearance='transparent']) .control { + border-color: transparent; + color: ${colorNeutralForeground2BrandSelected}; + } + + :host([aria-pressed='true'][appearance='transparent']:hover) .control { + color: ${colorNeutralForeground2BrandHover}; + } + + :host([aria-pressed='true'][appearance='transparent']:active) .control { + color: ${colorNeutralForeground2BrandPressed}; + } +`; diff --git a/packages/web-components/src/toggle-button/toggle-button.template.ts b/packages/web-components/src/toggle-button/toggle-button.template.ts new file mode 100644 index 0000000000000..13cf179fc8635 --- /dev/null +++ b/packages/web-components/src/toggle-button/toggle-button.template.ts @@ -0,0 +1,9 @@ +import { ElementViewTemplate } from '@microsoft/fast-element'; +import { buttonTemplate } from '@microsoft/fast-foundation'; +import type { ToggleButton } from './toggle-button.js'; + +/** + * The template for the ToggleButton component. + * @public + */ +export const template: ElementViewTemplate = buttonTemplate(); diff --git a/packages/web-components/src/toggle-button/toggle-button.ts b/packages/web-components/src/toggle-button/toggle-button.ts new file mode 100644 index 0000000000000..d30e49bfc201d --- /dev/null +++ b/packages/web-components/src/toggle-button/toggle-button.ts @@ -0,0 +1,104 @@ +import { attr, observable } from '@microsoft/fast-element'; +import { Button } from '../button/button.js'; + +/** + * The base class used for constructing a fluent-toggle-button custom element + * @public + */ +export class ToggleButton extends Button { + /** + * Tracks whether the "checked" property has been changed. + * This is necessary to provide consistent behavior with + * normal input checkboxes + */ + protected dirtyChecked: boolean = false; + + /** + * Provides the default checkedness of the input element + * Passed down to proxy + * + * @public + * @remarks + * HTML Attribute: checked + */ + @attr({ attribute: 'checked', mode: 'boolean' }) + public checkedAttribute: boolean = false; + protected checkedAttributeChanged(): void { + this.defaultChecked = this.checkedAttribute; + } + + @observable + public defaultChecked: boolean = false; + protected defaultCheckedChanged(): void { + if (!this.dirtyChecked) { + // Setting this.checked will cause us to enter a dirty state, + // but if we are clean when defaultChecked is changed, we want to stay + // in a clean state, so reset this.dirtyChecked + this.checked = this.defaultChecked; + this.dirtyChecked = false; + } + } + + /** + * The checked state of the control. + * + * @public + */ + @observable + public checked: boolean = false; + protected checkedChanged(prev: boolean | undefined, next: boolean): void { + if (!this.dirtyChecked) { + this.dirtyChecked = true; + } + + this.currentChecked = this.checked; + + ((this as unknown) as HTMLElement).setAttribute('aria-pressed', `${this.currentChecked}`); + + if (prev !== undefined) { + this.$emit('change'); + } + } + + /** + * The current checkedness of the element. This property serves as a mechanism + * to set the `checked` property through both property assignment and the + * .setAttribute() method. This is useful for setting the field's checkedness + * in UI libraries that bind data through the .setAttribute() API + * and don't support IDL attribute binding. + */ + @attr({ attribute: 'current-checked', mode: 'boolean' }) + public currentChecked: boolean = false; + public currentCheckedChanged(prev: boolean | undefined, next: boolean) { + this.checked = this.currentChecked; + } + + constructor() { + super(); + + // Re-initialize dirtyChecked because initialization of other values + // causes it to become true + this.dirtyChecked = false; + } + + public connectedCallback() { + super.connectedCallback(); + + ((this as unknown) as HTMLElement).addEventListener('click', this.handleToggleButtonClick); + } + + public disconnectedCallback() { + super.disconnectedCallback(); + + ((this as unknown) as HTMLElement).removeEventListener('click', this.handleToggleButtonClick); + } + + /** + * @internal + */ + protected handleToggleButtonClick = (e: MouseEvent): void => { + if (!this.disabled && !this.disabledFocusable) { + this.checked = !this.checked; + } + }; +} From 90a98b48775ef75b2251aa7e203596ca6f4bf86e Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Wed, 12 Apr 2023 04:19:42 +0000 Subject: [PATCH 077/203] applying package updates --- ...-23fff9de-b107-430a-b67b-d0d5f26212e1.json | 7 ----- ...-6f5897dc-d10c-4bbc-941b-54a948630c4c.json | 7 ----- ...-b7e6d7ad-6aac-4ccb-b7ee-97424d76f9a2.json | 7 ----- packages/web-components/CHANGELOG.json | 27 +++++++++++++++++++ packages/web-components/CHANGELOG.md | 13 ++++++++- packages/web-components/package.json | 2 +- 6 files changed, 40 insertions(+), 23 deletions(-) delete mode 100644 change/@fluentui-web-components-23fff9de-b107-430a-b67b-d0d5f26212e1.json delete mode 100644 change/@fluentui-web-components-6f5897dc-d10c-4bbc-941b-54a948630c4c.json delete mode 100644 change/@fluentui-web-components-b7e6d7ad-6aac-4ccb-b7ee-97424d76f9a2.json diff --git a/change/@fluentui-web-components-23fff9de-b107-430a-b67b-d0d5f26212e1.json b/change/@fluentui-web-components-23fff9de-b107-430a-b67b-d0d5f26212e1.json deleted file mode 100644 index 4fe7cd7d58f80..0000000000000 --- a/change/@fluentui-web-components-23fff9de-b107-430a-b67b-d0d5f26212e1.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat(toggle-button): add toggle button web component", - "packageName": "@fluentui/web-components", - "email": "chhol@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-6f5897dc-d10c-4bbc-941b-54a948630c4c.json b/change/@fluentui-web-components-6f5897dc-d10c-4bbc-941b-54a948630c4c.json deleted file mode 100644 index 23047291676d1..0000000000000 --- a/change/@fluentui-web-components-6f5897dc-d10c-4bbc-941b-54a948630c4c.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat(compound-button): add compound button as new web component", - "packageName": "@fluentui/web-components", - "email": "chhol@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-web-components-b7e6d7ad-6aac-4ccb-b7ee-97424d76f9a2.json b/change/@fluentui-web-components-b7e6d7ad-6aac-4ccb-b7ee-97424d76f9a2.json deleted file mode 100644 index d7029605e6490..0000000000000 --- a/change/@fluentui-web-components-b7e6d7ad-6aac-4ccb-b7ee-97424d76f9a2.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat(anchor-button): add anchor button to web components", - "packageName": "@fluentui/web-components", - "email": "chhol@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 5ac5d85c3c147..1cac261ec8852 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,33 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Wed, 12 Apr 2023 04:19:35 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.17", + "version": "3.0.0-alpha.17", + "comments": { + "prerelease": [ + { + "author": "chhol@microsoft.com", + "package": "@fluentui/web-components", + "commit": "cc0a6678ff55f657b13b70cff02645fe3772c84e", + "comment": "feat(toggle-button): add toggle button web component" + }, + { + "author": "chhol@microsoft.com", + "package": "@fluentui/web-components", + "commit": "37195a34b36538ab0cc7c765824691bab796502e", + "comment": "feat(compound-button): add compound button as new web component" + }, + { + "author": "chhol@microsoft.com", + "package": "@fluentui/web-components", + "commit": "5ab8f95663fcac978d98dccc65626196679a2ae2", + "comment": "feat(anchor-button): add anchor button to web components" + } + ] + } + }, { "date": "Tue, 11 Apr 2023 04:24:57 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.16", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index 9f5b0c2b07851..caadf7f3e35d6 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,20 @@ # Change Log - @fluentui/web-components -This log was last generated on Tue, 11 Apr 2023 04:24:57 GMT and should not be manually modified. +This log was last generated on Wed, 12 Apr 2023 04:19:35 GMT and should not be manually modified. +## [3.0.0-alpha.17](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.17) + +Wed, 12 Apr 2023 04:19:35 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.16..@fluentui/web-components_v3.0.0-alpha.17) + +### Changes + +- feat(toggle-button): add toggle button web component ([PR #27405](https://github.com/microsoft/fluentui/pull/27405) by chhol@microsoft.com) +- feat(compound-button): add compound button as new web component ([PR #27407](https://github.com/microsoft/fluentui/pull/27407) by chhol@microsoft.com) +- feat(anchor-button): add anchor button to web components ([PR #27395](https://github.com/microsoft/fluentui/pull/27395) by chhol@microsoft.com) + ## [3.0.0-alpha.16](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.16) Tue, 11 Apr 2023 04:24:57 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 3474005383b15..50179357ea1a1 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.16", + "version": "3.0.0-alpha.17", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 77a595641eab5428d12972373d2bb002b060ceff Mon Sep 17 00:00:00 2001 From: Ryan Merrill Date: Tue, 18 Apr 2023 17:35:18 -0400 Subject: [PATCH 078/203] Users/procload/add select spec (#27360) * Authors the Select spec * Cleans up some missing info in Spec * Removes references to Slider --- ...-0179648b-9385-4905-90ad-4fd47ad7f323.json | 7 ++ .../web-components/src/select/select.spec.md | 116 ++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 change/@fluentui-web-components-0179648b-9385-4905-90ad-4fd47ad7f323.json create mode 100644 packages/web-components/src/select/select.spec.md diff --git a/change/@fluentui-web-components-0179648b-9385-4905-90ad-4fd47ad7f323.json b/change/@fluentui-web-components-0179648b-9385-4905-90ad-4fd47ad7f323.json new file mode 100644 index 0000000000000..d7375ef68f8ff --- /dev/null +++ b/change/@fluentui-web-components-0179648b-9385-4905-90ad-4fd47ad7f323.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "Adds Select spec", + "packageName": "@fluentui/web-components", + "email": "ryan@ryanmerrill.net", + "dependentChangeType": "none" +} diff --git a/packages/web-components/src/select/select.spec.md b/packages/web-components/src/select/select.spec.md new file mode 100644 index 0000000000000..7b31d02c1877e --- /dev/null +++ b/packages/web-components/src/select/select.spec.md @@ -0,0 +1,116 @@ +# Select + +## Component Description + +The browser-native select control component allows users to choose one option from a list of options. It is commonly used in forms for selecting values from a predefined set of options. This component is a wrapper for the browser-native select control and largely exists to provide a consistent API across browsers, especially on mobile devices. + +## Design Spec + +[Link to Design Spec in Figma](https://www.figma.com/file/0vOH481cv1VQyfQIX9JALn/Select?node-id=1319-163&t=nn2xgT4ieHjbkqQW-11) + +## Engineering Spec + +### Inputs + +- @attr appearance: "outline" "underline" "filled-darker" "filled-lighter" | "outline" +- @attr component-size: "small" "medium" "large" | "medium" +- @attr disabled: boolean +- @attr required: boolean +- @attr name: string +- @attr autofocus: boolean +- @attr autocomplete: "on" "off" | "off" +- @attr aria-label: string +- @attr aria-labelledby: string +- @attr aria-describedby: string +- Use ARIAGlobalStatesAndProperties from @microsoft/fast-foundation +- No @attr for multiple as it is not supported in the Fluent React implementation + +### Outputs + +None + +### Events + +- @input: Fires whenever the value of the `select` has been changed +- @change: Fires whenever the user modifies the value of `select` +- Note: These will not be the native events, but will be custom events that bubble + +### Slots + +- default: The dfeault for `option` and `optgroup` elements. As these are the only elements supported in the native `select` control, we will filter out any other elements that are slotted. +- icon: the icon, typically a down arrow +- label: the label for the select, optional +- Example usage for default slot + ```HTML + + + + + + + + + ``` + +### CSS Variables + +None + +## Accessibility + +- [x] Find the matching component through WCAG's patterns: https://www.w3.org/WAI/ARIA/apg/patterns/ + - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select +- [x] Are there any accessibility elements unique to this component? +- [x] List ARIA attributes + - @attr aria-label: string + - @attr aria-labelledby: string + - @attr aria-describedby: string + - Use ARIAGlobalStatesAndProperties from @microsoft/fast-foundation +- [x] Does the component support 400% zoom? +- [x] What keyboard behaviors does the component support? + - Up / Down : Moves focus between options + - Space / Enter: Selects the focused option + - Home : Sets focus to the first option + - End : Sets focus to the last option + - Esc : Closes the dropdown list if it is open + - Page Up / Down : Moves focus between options + +## Preparation + +- [x] [Find the base FAST Component](https://explore.fast.design/components/) this component will inherit from and document + - This will be a wrapper for the browser-native select control and does not have a corresponding FAST component +- [x] [Check the Fluent UI React V9 Component Spec](https://github.com/microsoft/fluentui/tree/master/specs) for differences and document + - No spec available +- [x] [Fluent UI React V9 Storybook](https://aka.ms/fluentui-storybook) for implementation differences and document + - [Fluent React V9 Select](https://master--628d031b55e942004ac95df1.chromatic.com/?path=/docs/components-select--default) + - `size` attribute renamed to `component-size` to not conflict with the HTML `size` attribute +- [x] [Open GitHub issues related to component](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#find-open-issues-on-github) + - [Select](https://github.com/orgs/microsoft/projects/652/views/2?pane=issue&itemId=18315933) +- [ ] (Optional) [Draft implementation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#draft-implementation) + - [link to draft implementation, if applicable] +- [x] [Component Spec authored](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#component-spec) + - [ ] And [reviewed](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#spec-review) + +## Implementation + +- [ ] Initial conformance and unit tests (validate basic functionality) +- [ ] [Initial documentation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#documentation) + - [ ] [Storybook stories](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#storybook-stories) + - [ ] README.md covering basic usage +- [ ] Uses design tokens for styling +- [ ] Renders correctly in High Contrast mode + +## Validation + +- [ ] [Add tests](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#tests) + - [ ] Unit and conformance tests + - [ ] Bundle size fixtures + - [ ] Performance test scenario + - [ ] Accessibility behavior tests + - [ ] Create an issue and run [manual accessibility tests](https://github.com/microsoft/fluentui/wiki/Manual-Accessibility-Review-Checklist): [link to issue] +- [ ] [Validate with partners](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#validation) +- [ ] [Finalize documentation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#finalize-documentation) + - [ ] Review and add any missing Storybook stories + - [ ] Finalize migration guide + - [ ] In package.json: Remove the alpha/beta tag from the version number in package.json + - [ ] In package.json: Change beachball's `disallowedChangeTypes` to `"major", "prerelease"` From aed6dfcc601f0a0201cf8d3dea33dbf9fbbb9fe9 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Wed, 19 Apr 2023 04:23:38 +0000 Subject: [PATCH 079/203] applying package updates --- ...ents-0179648b-9385-4905-90ad-4fd47ad7f323.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 change/@fluentui-web-components-0179648b-9385-4905-90ad-4fd47ad7f323.json diff --git a/change/@fluentui-web-components-0179648b-9385-4905-90ad-4fd47ad7f323.json b/change/@fluentui-web-components-0179648b-9385-4905-90ad-4fd47ad7f323.json deleted file mode 100644 index d7375ef68f8ff..0000000000000 --- a/change/@fluentui-web-components-0179648b-9385-4905-90ad-4fd47ad7f323.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "Adds Select spec", - "packageName": "@fluentui/web-components", - "email": "ryan@ryanmerrill.net", - "dependentChangeType": "none" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 1cac261ec8852..cef86fc5612c6 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Wed, 19 Apr 2023 04:23:30 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.17", + "version": "3.0.0-alpha.17", + "comments": { + "none": [ + { + "author": "ryan@ryanmerrill.net", + "package": "@fluentui/web-components", + "commit": "e5ff319c5354a9f47d6f5b990441673e32998b7c", + "comment": "Adds Select spec" + } + ] + } + }, { "date": "Wed, 12 Apr 2023 04:19:35 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.17", From 2346d39726626bf902887bce83966e9918c27336 Mon Sep 17 00:00:00 2001 From: Hale Rankin Date: Wed, 19 Apr 2023 10:00:33 -0700 Subject: [PATCH 080/203] Update: Modify Image Web Component Styles (#27567) * Updates story with better placeholder images. Updates styles to ensure that shadow, shape and border work correctly when fit is center. Sets default border-radius and updates storybook shape description with detail about the default border radius. * Yarn change * Reverts style changes. Adds only essential style adjustments to meet spec. Updates attribute descriptions in the story. * Removes pixel value in description for design token: borderRadiusMedium. --- ...-482b832c-2b9e-4712-a120-a20052caf778.json | 7 +++ .../web-components/src/image/image.stories.ts | 46 ++++++++++--------- .../web-components/src/image/image.styles.ts | 11 ++++- 3 files changed, 42 insertions(+), 22 deletions(-) create mode 100644 change/@fluentui-web-components-482b832c-2b9e-4712-a120-a20052caf778.json diff --git a/change/@fluentui-web-components-482b832c-2b9e-4712-a120-a20052caf778.json b/change/@fluentui-web-components-482b832c-2b9e-4712-a120-a20052caf778.json new file mode 100644 index 0000000000000..c7e5e479567e9 --- /dev/null +++ b/change/@fluentui-web-components-482b832c-2b9e-4712-a120-a20052caf778.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Image component style updates", + "packageName": "@fluentui/web-components", + "email": "harankin@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/src/image/image.stories.ts b/packages/web-components/src/image/image.stories.ts index b5ed33ed14daa..e81972f843abf 100644 --- a/packages/web-components/src/image/image.stories.ts +++ b/packages/web-components/src/image/image.stories.ts @@ -17,7 +17,7 @@ const imageTemplate = html` ?shadow=${x => x.shadow} shape=${x => x.shape} > - Short image description + Short image description
`; @@ -98,6 +98,10 @@ export default { defaultValue: { summary: 'square', }, + type: { + summary: + 'When shape `rounded` is used, default border radius is `borderRadiusMedium`. The dev may override the default border radius using one of the following: borderRadiusSmall, borderRadiusLarge, borderRadiusXLarge.', + }, }, options: Object.values(ImageShape), control: 'select', @@ -119,8 +123,8 @@ export const Image = renderComponent(imageTemplate).bind({}); const imageLayoutBlock = html`
- - + +
`; @@ -128,18 +132,18 @@ export const BlockLayout = renderComponent(imageLayoutBlock).bind({}); // Fit: None const imageFitNoneLarge = html` -
+
- +
`; export const ImageFitNoneLarge = renderComponent(imageFitNoneLarge).bind({}); const imageFitNoneSmall = html` -
+
- 200x100 placeholder + 200x100 placeholder
`; @@ -147,27 +151,27 @@ export const ImageFitNoneSmall = renderComponent(imageFitNoneSmall).bind({}); // Fit: Center const imageFitCenterLarge = html` -
- - +
+ +
`; export const ImageFitCenterLarge = renderComponent(imageFitCenterLarge).bind({}); const imageFitCenterSmall = html` -
- - image layout story +
+ + image layout story
`; export const ImageFitCenterSmall = renderComponent(imageFitCenterSmall).bind({}); const imageFitContain = html` -
+
- image layout story + image layout story
`; @@ -176,7 +180,7 @@ export const ImageFitContain = renderComponent(imageFitContain).bind({}); const imageFitContainTall = html`
- image layout story + image layout story
`; @@ -185,7 +189,7 @@ export const ImageFitContainTall = renderComponent(imageFitContainTall).bind({}) const imageFitContainWide = html`
- image layout story + image layout story
`; @@ -195,7 +199,7 @@ export const ImageFitContainWide = renderComponent(imageFitContainWide).bind({}) const imageFitCoverSmall = html`
- image layout story + image layout story
`; @@ -204,7 +208,7 @@ export const ImageFitCoverSmall = renderComponent(imageFitCoverSmall).bind({}); const imageFitCoverMedium = html`
- image layout story + image layout story
`; @@ -213,7 +217,7 @@ export const ImageFitCoverMedium = renderComponent(imageFitCoverMedium).bind({}) const imageFitCoverLarge = html`
- image layout story + image layout story
`; @@ -223,7 +227,7 @@ export const ImageFitCoverLarge = renderComponent(imageFitCoverLarge).bind({}); const imageFitDefault = html`
- image layout story + image layout story
`; diff --git a/packages/web-components/src/image/image.styles.ts b/packages/web-components/src/image/image.styles.ts index 8437b18943ef9..ee49997014ecf 100644 --- a/packages/web-components/src/image/image.styles.ts +++ b/packages/web-components/src/image/image.styles.ts @@ -1,5 +1,11 @@ import { css } from '@microsoft/fast-element'; -import { borderRadiusCircular, colorNeutralStroke2, shadow4, strokeWidthThin } from '../theme/design-tokens.js'; +import { + borderRadiusCircular, + borderRadiusMedium, + colorNeutralStroke2, + shadow4, + strokeWidthThin, +} from '../theme/design-tokens.js'; /** Image styles * @@ -53,4 +59,7 @@ export const styles = css` :host([shape='circular']) ::slotted(img) { border-radius: ${borderRadiusCircular}; } + :host([shape='rounded']) ::slotted(img) { + border-radius: ${borderRadiusMedium}; + } `; From 0b580240e7dcf4ea77f5ffc2d718c3f4fff24a0e Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Thu, 20 Apr 2023 04:20:36 +0000 Subject: [PATCH 081/203] applying package updates --- ...ents-482b832c-2b9e-4712-a120-a20052caf778.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) delete mode 100644 change/@fluentui-web-components-482b832c-2b9e-4712-a120-a20052caf778.json diff --git a/change/@fluentui-web-components-482b832c-2b9e-4712-a120-a20052caf778.json b/change/@fluentui-web-components-482b832c-2b9e-4712-a120-a20052caf778.json deleted file mode 100644 index c7e5e479567e9..0000000000000 --- a/change/@fluentui-web-components-482b832c-2b9e-4712-a120-a20052caf778.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "Image component style updates", - "packageName": "@fluentui/web-components", - "email": "harankin@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index cef86fc5612c6..d8ee5e218fd07 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Thu, 20 Apr 2023 04:20:30 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.18", + "version": "3.0.0-alpha.18", + "comments": { + "prerelease": [ + { + "author": "harankin@microsoft.com", + "package": "@fluentui/web-components", + "commit": "9cd641f4d38d6889ee50afeedca54f77617cd1a5", + "comment": "Image component style updates" + } + ] + } + }, { "date": "Wed, 19 Apr 2023 04:23:30 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.17", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index caadf7f3e35d6..8dcec536d6eca 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Wed, 12 Apr 2023 04:19:35 GMT and should not be manually modified. +This log was last generated on Thu, 20 Apr 2023 04:20:30 GMT and should not be manually modified. +## [3.0.0-alpha.18](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.18) + +Thu, 20 Apr 2023 04:20:30 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.17..@fluentui/web-components_v3.0.0-alpha.18) + +### Changes + +- Image component style updates ([PR #27567](https://github.com/microsoft/fluentui/pull/27567) by harankin@microsoft.com) + ## [3.0.0-alpha.17](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.17) Wed, 12 Apr 2023 04:19:35 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 50179357ea1a1..ecde02e6ede6d 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.17", + "version": "3.0.0-alpha.18", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 0f8c7ac1da374b121485e8bbdd37d8f7131558b0 Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Thu, 20 Apr 2023 13:13:30 -0700 Subject: [PATCH 082/203] Adds Menu and MenuItem as new web components (#26765) * menu init * updates docs * menu init * menu item init * registers menu-item * adds some menu styles * adds default menu item icons * adds menu stories * updates default menu icons * styles menu and menu item * updates readme * swaps part for class css * removes dead code * adds menu and menu item to package.json * removes dead code * updates menu styles * yarn change * adds menu header * updates jsdocs * removes dead file * removes dead code * removes split button styling * adds display helper * api report * flattens menu and menu item directories * removes element specification from slotted selector * formatting * optimizes styles * optmizes styles * updates disabled css selector to bool * removes dead code * consolidates menu docs into one story * updates menu storybook content * optimizes styling * revert api-report * updates disabled pseudo selector * fixes disabled state * fixes css syntax error * updates storybook content * updates storybook copy for consistency * revert api report * updates yarn change message * maps component to MenuList rather than Menu * fixes focus state * updates styles * divides accordion and accordion item readme * removes dead imports * fixes submenu positioning * adds styles for icon alignment * reverts Menu component name * cleans up storybook * dynamically set the menu item icon attribute when icons is true for menu (#26998) * dynamically set the menu item icon attribute when icons is true for menu * move icons check to set items to ensure we update on item change and init * set items should be protected * updates Menu styles * updates icon alignment styles and docs * updates menu docs * adds checkmarks attribute and styles menu items * adds conditional styling for when icons are present * updates Menu and MenuItem docs * updates deltas in docs * updates docs * optimizes styles * optimizes css * optimizes css * optimizes css * reverts json export * working (#27293) * optimizes styles * adds docs to menu.ts * updates menu logic for readability * menu: fixes style syntax error * menu: consolidates styles * menu: updates styling * menu: updates styling * yarn change * menulist, menuitem: changes component name to MenuList * menulist, menuitem, updates readme * menu, menuitem: fixes circular dep * menu, menuitem: alphabetize index.js --------- Co-authored-by: Chris Holt Co-authored-by: Jeff Smith <37851214+eljefe223@users.noreply.github.com> --- ...-e1aaa3a2-771d-4c16-b8d2-a56deb1fdd28.json | 7 + packages/web-components/package.json | 16 +- packages/web-components/src/index.ts | 2 + .../web-components/src/menu-item/README.md | 125 ++++++++ .../web-components/src/menu-item/define.ts | 4 + .../web-components/src/menu-item/index.ts | 4 + .../src/menu-item/menu-item.definition.ts | 19 ++ .../src/menu-item/menu-item.styles.ts | 203 ++++++++++++ .../src/menu-item/menu-item.template.ts | 17 ++ .../web-components/src/menu-item/menu-item.ts | 9 + .../web-components/src/menu-list/README.md | 104 +++++++ .../web-components/src/menu-list/define.ts | 4 + .../web-components/src/menu-list/index.ts | 4 + .../src/menu-list/menu-list.definition.ts | 19 ++ .../src/menu-list/menu-list.stories.ts | 289 ++++++++++++++++++ .../src/menu-list/menu-list.styles.ts | 29 ++ .../src/menu-list/menu-list.template.ts | 5 + .../web-components/src/menu-list/menu-list.ts | 43 +++ 18 files changed, 899 insertions(+), 4 deletions(-) create mode 100644 change/@fluentui-web-components-e1aaa3a2-771d-4c16-b8d2-a56deb1fdd28.json create mode 100644 packages/web-components/src/menu-item/README.md create mode 100644 packages/web-components/src/menu-item/define.ts create mode 100644 packages/web-components/src/menu-item/index.ts create mode 100644 packages/web-components/src/menu-item/menu-item.definition.ts create mode 100644 packages/web-components/src/menu-item/menu-item.styles.ts create mode 100644 packages/web-components/src/menu-item/menu-item.template.ts create mode 100644 packages/web-components/src/menu-item/menu-item.ts create mode 100644 packages/web-components/src/menu-list/README.md create mode 100644 packages/web-components/src/menu-list/define.ts create mode 100644 packages/web-components/src/menu-list/index.ts create mode 100644 packages/web-components/src/menu-list/menu-list.definition.ts create mode 100644 packages/web-components/src/menu-list/menu-list.stories.ts create mode 100644 packages/web-components/src/menu-list/menu-list.styles.ts create mode 100644 packages/web-components/src/menu-list/menu-list.template.ts create mode 100644 packages/web-components/src/menu-list/menu-list.ts diff --git a/change/@fluentui-web-components-e1aaa3a2-771d-4c16-b8d2-a56deb1fdd28.json b/change/@fluentui-web-components-e1aaa3a2-771d-4c16-b8d2-a56deb1fdd28.json new file mode 100644 index 0000000000000..1772b2b7ad1bf --- /dev/null +++ b/change/@fluentui-web-components-e1aaa3a2-771d-4c16-b8d2-a56deb1fdd28.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat(menu-list): Add menu-list and menu-item web components", + "packageName": "@fluentui/web-components", + "email": "brianbrady@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index ecde02e6ede6d..996a0464aa901 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -68,10 +68,18 @@ "types": "./dist/esm/label/define.d.ts", "default": "./dist/esm/label/define.js" }, + "./menu-list": { + "types": "./dist/esm/menu-list/define.d.ts", + "default": "./dist/esm/menu-list/define.js" + }, "./menu-button": { "types": "./dist/esm/menu-button/define.d.ts", "default": "./dist/esm/menu-button/define.js" }, + "./menu-item": { + "types": "./dist/esm/menu-item/define.d.ts", + "default": "./dist/esm/menu-item/define.js" + }, "./progress-bar": { "types": "./dist/esm/progress-bar/define.d.ts", "default": "./dist/esm/progress-bar/define.js" @@ -88,14 +96,14 @@ "types": "./dist/esm/switch/define.d.ts", "default": "./dist/esm/switch/define.js" }, - "./tabs": { - "types": "./dist/esm/tabs/define.d.ts", - "default": "./dist/esm/tabs/define.js" - }, "./tab": { "types": "./dist/esm/tab/define.d.ts", "default": "./dist/esm/tab/define.js" }, + "./tabs": { + "types": "./dist/esm/tabs/define.d.ts", + "default": "./dist/esm/tabs/define.js" + }, "./tab-panel": { "types": "./dist/esm/tab-panel/define.d.ts", "default": "./dist/esm/tab-panel/define.js" diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index b006d274be2b7..cfbb551238a38 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -10,6 +10,8 @@ export * from './divider/index.js'; export * from './image/index.js'; export * from './label/index.js'; export * from './menu-button/index.js'; +export * from './menu-item/index.js'; +export * from './menu-list/index.js'; export * from './progress-bar/index.js'; export * from './slider/index.js'; export * from './spinner/index.js'; diff --git a/packages/web-components/src/menu-item/README.md b/packages/web-components/src/menu-item/README.md new file mode 100644 index 0000000000000..3bba2d88611a9 --- /dev/null +++ b/packages/web-components/src/menu-item/README.md @@ -0,0 +1,125 @@ +# Menu Item + +Menu list item options displayed in a MenuList component. They are invoked when users interact with a button, action, or other control. + +
+ +
+ +**Remaining work items** + +2. Create support for menu item "grouping" +3. Split button variation + +
+
+
+ +## Design Spec + +[Link to Menu Item Design Spec in Figma](https://www.figma.com/file/jFWrkFq61GDdOhPlsz6AtX/Menu?node-id=1528%3A5102&t=XtW4laeEzgVFIl1E-0) + +
+
+
+ +## Engineering Spec + +Fluent WC3 Menu extends from the FAST Menu [FAST Menu Item](https://explore.fast.design/components/fast-menu) and is intended to be as close to the Fluent UI React 9 Menu implementation as possible. However, due to the nature of web components there will not be 100% parity between the two. + +
+ +### Inputs + +- `role` - an enum representing the menu items' role + - `menuitem` + - `menuitemcheckbox` + - `menuitemradio` +- `disabled` - the menu item is disabled +- `checked` - sets the checked value for menuitemcheckbox or menuitemradio items + +### Outputs + +- none + +### Events + +- `click` (event) - event for when the item has been clicked or invoked via keyboard +- `change` (event) - event for when the item has been clicked or invoked via keyboard, and will be prevented if the menu item is disabled +- `expanded-change` (event) - event for when the item has been expanded or collapsed + +### Slots + +- `before` - slot which precedes content +- `default` - slot for the content (the default slot for the item) +- `after` - slot which comes after content +- `submenu` - the slot used to generate a submenu +- `radio-indicator` - slot for radio item selection indicator +- `checkbox-indicator` - slot for the checkbox selection indicator +- `expand-collapse-glyph` - slot for the expand/collapse glyph for nested menus + +### CSS Variables + +- `borderRadiusMedium` +- `colorCompoundBrandForeground1Hover` +- `colorCompoundBrandForeground1Pressed` +- `colorNeutralBackground1` +- `colorNeutralBackground1Hover` +- `colorNeutralBackground1Pressed` +- `colorNeutralBackgroundDisabled` +- `colorNeutralForeground2` +- `colorNeutralForeground2Hover` +- `colorNeutralForeground2Pressed` +- `colorNeutralForeground3` +- `colorNeutralForegroundDisabled` +- `colorNeutralStrokeDisabled` +- `fontFamilyBase` +- `fontSizeBase200` +- `fontSizeBase300` +- `fontWeightRegular` +- `fontWeightSemibold` +- `lineHeightBase200` +- `lineHeightBase300` + +
+
+
+ +## Accessibility + +
+ +**ARIA Attributes** + +| Attribute | Options | Description | +| ------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------- | +| aria-checked | boolean | +| aria-disabled | boolean | indicates that the element is perceivable but disabled, so it is not editable or otherwise operable | +| role | `menuitem` \| `menuitemcheckbox` \| `menuitemradio` | an enum representing the menu items' role | + +
+
+ +## Preparation + +
+ +### **Fluent Web Component v3 v.s Fluent React 9** + +Due to the nature of Web Components there will not be 100% parity between component implementation in Fluent UI React v9 and Fluent Web Components v3. + +
+ +**Component, Slot, and Attribute Mapping** +Component, Slot, or Attribute | Fluent React v9 | Fluent Web Components v3 | +---------------------------------| ---------------------| ---------------------------| +Menu | `` | `` | +Menu item |`` | `` | +Menu item with radio | `` | `..` | +Menu item with checkbox | `` | `..` | +Icons | `}>` | `..`
`..`| +Menu group header | `` | ``| + +**Additional Deltas** + +In order for icons to render with appropriate styles the `icons` attribute must be present on the Menu. diff --git a/packages/web-components/src/menu-item/define.ts b/packages/web-components/src/menu-item/define.ts new file mode 100644 index 0000000000000..5601bcf73fa65 --- /dev/null +++ b/packages/web-components/src/menu-item/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './menu-item.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/menu-item/index.ts b/packages/web-components/src/menu-item/index.ts new file mode 100644 index 0000000000000..9e57815928612 --- /dev/null +++ b/packages/web-components/src/menu-item/index.ts @@ -0,0 +1,4 @@ +export * from './menu-item.js'; +export { template as MenuItemTemplate } from './menu-item.template.js'; +export { styles as MenuItemStyles } from './menu-item.styles.js'; +export { definition as MenuItemDefinition } from './menu-item.definition.js'; diff --git a/packages/web-components/src/menu-item/menu-item.definition.ts b/packages/web-components/src/menu-item/menu-item.definition.ts new file mode 100644 index 0000000000000..a923d901bcefc --- /dev/null +++ b/packages/web-components/src/menu-item/menu-item.definition.ts @@ -0,0 +1,19 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { MenuItem } from './menu-item.js'; +import { styles } from './menu-item.styles.js'; +import { template } from './menu-item.template.js'; + +/** + * The Fluent Menu Item Element. Implements {@link @microsoft/fast-foundation#MenuItem }, + * {@link @microsoft/fast-foundation#menuItemTemplate} + * + * + * @public + * @remarks + * HTML Element: + */ +export const definition = MenuItem.compose({ + name: `${FluentDesignSystem.prefix}-menu-item`, + template, + styles, +}); diff --git a/packages/web-components/src/menu-item/menu-item.styles.ts b/packages/web-components/src/menu-item/menu-item.styles.ts new file mode 100644 index 0000000000000..a50fb2173d2bc --- /dev/null +++ b/packages/web-components/src/menu-item/menu-item.styles.ts @@ -0,0 +1,203 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + borderRadiusMedium, + colorCompoundBrandForeground1Hover, + colorCompoundBrandForeground1Pressed, + colorNeutralBackground1, + colorNeutralBackground1Hover, + colorNeutralBackground1Selected, + colorNeutralBackgroundDisabled, + colorNeutralForeground2, + colorNeutralForeground2Hover, + colorNeutralForeground2Pressed, + colorNeutralForeground3, + colorNeutralForegroundDisabled, + fontFamilyBase, + fontSizeBase200, + fontSizeBase300, + fontSizeBase500, + fontWeightRegular, + lineHeightBase200, + lineHeightBase300, +} from '../theme/design-tokens.js'; + +/** MenuItem styles + * @public + */ +export const styles = css` + ${display('grid')} + + :host { + grid-template-columns: 20px 20px auto 20px; + align-items: center; + grid-gap: 4px; + height: 32px; + background: ${colorNeutralBackground1}; + font: ${fontWeightRegular} ${fontSizeBase300} / ${lineHeightBase300} ${fontFamilyBase}; + border-radius: ${borderRadiusMedium}; + color: ${colorNeutralForeground2}; + padding: 0 10px; + cursor: pointer; + overflow: visible; + contain: layout; + } + + :host(:hover) { + background: ${colorNeutralBackground1Hover}; + } + + .content { + white-space: nowrap; + flex-grow: 1; + grid-column: auto / span 2; + padding: 0 2px; + } + + .checkbox, + .radio { + display: none; + } + + .input-container, + .expand-collapse-glyph-container, + ::slotted([slot='start']), + ::slotted([slot='end']), + :host([checked]) .checkbox, + :host([checked]) .radio { + display: inline-flex; + justify-content: center; + align-items: center; + color: ${colorNeutralForeground2}; + } + + .expand-collapse-glyph-container, + ::slotted([slot='start']), + ::slotted([slot='end']) { + height: 32px; + font-size: ${fontSizeBase500}; + width: fit-content; + } + + .input-container { + width: 20px; + } + + ::slotted([slot='end']) { + color: ${colorNeutralForeground3}; + font: ${fontWeightRegular} ${fontSizeBase200} / ${lineHeightBase200} ${fontFamilyBase}; + white-space: nowrap; + grid-column: 4 / span 1; + justify-self: flex-end; + } + + .expand-collapse-glyph-container { + grid-column: 4 / span 1; + justify-self: flex-end; + } + + :host(:hover) .input-container, + :host(:hover) .expand-collapse-glyph-container, + :host(:hover) .content { + color: ${colorNeutralForeground2Hover}; + } + + :host([icon]:hover) ::slotted([slot='start']) { + color: ${colorCompoundBrandForeground1Hover}; + } + + :host(:active) { + background-color: ${colorNeutralBackground1Selected}; + } + + :host(:active) .input-container, + :host(:active) .expand-collapse-glyph-container, + :host(:active) .content { + color: ${colorNeutralForeground2Pressed}; + } + + :host(:active) ::slotted([slot='start']) { + color: ${colorCompoundBrandForeground1Pressed}; + } + + :host([disabled]) { + background-color: ${colorNeutralBackgroundDisabled}; + } + + :host([disabled]) .content, + :host([disabled]) .expand-collapse-glyph-container, + :host([disabled]) ::slotted([slot='end']), + :host([disabled]) ::slotted([slot='start']) { + color: ${colorNeutralForegroundDisabled}; + } + + :host([data-indent]) { + display: grid; + } + + :host([data-indent='1']) .content { + grid-column: 2 / span 1; + } + + :host([data-indent='1'][role='menuitemcheckbox']) { + display: grid; + } + + :host([data-indent='2'][aria-haspopup='menu']) ::slotted([slot='end']) { + grid-column: 4 / span 1; + } + + :host([data-indent='2'][aria-haspopup='menu']) .expand-collapse-glyph-container { + grid-column: 5 / span 1; + } + + :host([data-indent='1']) .content { + grid-column: 2 / span 1; + } + + :host([data-indent='1'][role='menuitemcheckbox']) .content, + :host([data-indent='1'][role='menuitemradio']) .content { + grid-column: auto / span 1; + } + + :host([icon]) ::slotted([slot='end']), + :host([data-indent='1']) ::slotted([slot='end']) { + grid-column: 4 / span 1; + justify-self: flex-end; + } + + :host([data-indent='2']) { + display: grid; + grid-template-columns: 20px 20px auto auto; + } + + :host([data-indent='2']) .content { + grid-column: 3 / span 1; + } + + :host([data-indent='2']) .input-container { + grid-column: 1 / span 1; + } + + :host([data-indent='2']) ::slotted([slot='start']) { + grid-column: 2 / span 1; + } + + :host([aria-haspopup='menu']) { + grid-template-columns: 20px auto auto 20px; + } + + :host([data-indent='2'][aria-haspopup='menu']) { + grid-template-columns: 20px 20px auto auto 20px; + } + + :host([aria-haspopup='menu']) ::slotted([slot='end']) { + grid-column: 3 / span 1; + justify-self: flex-end; + } + + :host([data-indent='2'][aria-haspopup='menu']) ::slotted([slot='end']) { + grid-column: 4 / span 1; + justify-self: flex-end; + } +`; diff --git a/packages/web-components/src/menu-item/menu-item.template.ts b/packages/web-components/src/menu-item/menu-item.template.ts new file mode 100644 index 0000000000000..2d0a5a480b206 --- /dev/null +++ b/packages/web-components/src/menu-item/menu-item.template.ts @@ -0,0 +1,17 @@ +import { ElementViewTemplate } from '@microsoft/fast-element'; +import { html } from '@microsoft/fast-element'; +import { menuItemTemplate } from '@microsoft/fast-foundation'; +import type { MenuItem } from './menu-item.js'; + +const Checkmark16Filled = html.partial( + ``, +); +const chevronRight16Filled = html.partial( + ``, +); + +export const template: ElementViewTemplate = menuItemTemplate({ + checkboxIndicator: Checkmark16Filled, + expandCollapseGlyph: chevronRight16Filled, + radioIndicator: Checkmark16Filled, +}); diff --git a/packages/web-components/src/menu-item/menu-item.ts b/packages/web-components/src/menu-item/menu-item.ts new file mode 100644 index 0000000000000..e472e6bc2208b --- /dev/null +++ b/packages/web-components/src/menu-item/menu-item.ts @@ -0,0 +1,9 @@ +import { FASTMenuItem } from '@microsoft/fast-foundation'; + +export type MenuItemColumnCount = 0 | 1 | 2; + +/** + * The base class used for constructing a fluent-menu-item custom element + * @public + */ +export class MenuItem extends FASTMenuItem {} diff --git a/packages/web-components/src/menu-list/README.md b/packages/web-components/src/menu-list/README.md new file mode 100644 index 0000000000000..9710c2e2f9ab4 --- /dev/null +++ b/packages/web-components/src/menu-list/README.md @@ -0,0 +1,104 @@ +# MenuList + +The MenuList displays a list of MenuItem options. + +## Design Spec + +[Link to MenuList Design Spec in Figma](https://www.figma.com/file/jFWrkFq61GDdOhPlsz6AtX/Menu?node-id=1528%3A5102&t=XtW4laeEzgVFIl1E-0) + +## Engineering Spec + +Fluent WC3 MenuList extends from the FAST Menu [FAST Menu](https://explore.fast.design/components/fast-menu) and is intended to be as close to the Fluent UI React 9 MenuList implementation as possible. However, due to the nature of web components there will not be 100% parity between the two. + +
+ +### Inputs + +### Outputs + +- none + +### Events + +- none + +### Slots + +- default slot for items + +### CSS Variables + +- `colorNeutralBackground1` +- `colorTransparentStroke` +- `borderRadiusMedium` +- `shadow16` + +
+
+
+ +## Accessibility + +
+ +**ARIA Attributes** +Attribute | Options | Description +--------------|-----------------|------------| +aria-checked | boolean | +aria-disabled | boolean | indicates that the element is perceivable but disabled, so it is not editable or otherwise operable +role | `menuitem` `menuitemcheckbox` `menuitemradio` | an enum representing the menu items' role + +
+
+
+ +## Preparation + +
+ +### **Fluent Web Component v3 v.s Fluent React 9** + +Due to the nature of Web Components there will not be 100% parity between component implementation in Fluent UI React v9 and Fluent Web Components v3. +
+ +**Component, Slot, and Attribute Mapping** +Component, Slot, or Attribute | Fluent React v9 | Fluent Web Components v3 | +--------------------------------|--------------------------------| -----------------------------------------------------| +Menu | `` | `` | +Menu item | `` | `` | +Menu item with radio | `` | `..` | +Menu item with checkbox | `` | `..` | +Icons | `}>` | `..`
`..` | +Aligning Icons | `` | aligns by default | +Aligning Checkboxes | `` | aligns by default | +Menu group header | `` | `` | + +
+ +**Additional Deltas:** + +**Responsiveness** + +The WC3 MenuList component does not currently support responsive styling. + +**Composure** + +Complete FUIR9 Menu composure + +```html + + Item 1 + Item 2 + Item 3 + +``` + +Complete WC3 Menu composure + +```html + + Item 1 + Item 2 + Item 3 + +``` diff --git a/packages/web-components/src/menu-list/define.ts b/packages/web-components/src/menu-list/define.ts new file mode 100644 index 0000000000000..fb0f26fd1ced4 --- /dev/null +++ b/packages/web-components/src/menu-list/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './menu-list.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/menu-list/index.ts b/packages/web-components/src/menu-list/index.ts new file mode 100644 index 0000000000000..3448cf03ccf19 --- /dev/null +++ b/packages/web-components/src/menu-list/index.ts @@ -0,0 +1,4 @@ +export * from './menu-list.js'; +export { template as MenuListTemplate } from './menu-list.template.js'; +export { styles as MenuListStyles } from './menu-list.styles.js'; +export { definition as MenuListDefinition } from './menu-list.definition.js'; diff --git a/packages/web-components/src/menu-list/menu-list.definition.ts b/packages/web-components/src/menu-list/menu-list.definition.ts new file mode 100644 index 0000000000000..6806c1543c395 --- /dev/null +++ b/packages/web-components/src/menu-list/menu-list.definition.ts @@ -0,0 +1,19 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { MenuList } from './menu-list.js'; +import { styles } from './menu-list.styles.js'; +import { template } from './menu-list.template.js'; + +/** + * The Fluent MenuList Element. Implements {@link @microsoft/fast-foundation#Menu }, + * {@link @microsoft/fast-foundation#menuTemplate} + * + * + * @public + * @remarks + * HTML Element: + */ +export const definition = MenuList.compose({ + name: `${FluentDesignSystem.prefix}-menu-list`, + template, + styles, +}); diff --git a/packages/web-components/src/menu-list/menu-list.stories.ts b/packages/web-components/src/menu-list/menu-list.stories.ts new file mode 100644 index 0000000000000..98a6d84280e57 --- /dev/null +++ b/packages/web-components/src/menu-list/menu-list.stories.ts @@ -0,0 +1,289 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../helpers.stories.js'; +import type { MenuList as FluentMenuList } from './menu-list.js'; +import './define.js'; +import '../menu-item/define.js'; +import '../divider/define.js'; + +type MenuListStoryArgs = Args & FluentMenuList; +type MenuListStoryMeta = Meta; + +const Cut20Filled = html``; + +const Edit20Filled = html``; + +const Folder24Filled = html` + +`; +const Code20Filled = html``; + +const storyTemplate = html` +
+ + x.disabled}> + Item 1 + ${Cut20Filled} + Ctrl+X + + + x.disabled}> + ${Edit20Filled} + Item 2 + Ctrl+E + + + x.disabled}> Open + + + + x.disabled}> + Checkbox 1 + ${Cut20Filled} + + + x.disabled}> + Checkbox 2 + ${Edit20Filled} + + + x.disabled}> Checkbox 3 + + + + x.disabled}> + Radio 1 + ${Cut20Filled} + + + x.disabled}> + Radio 2 + ${Edit20Filled} + + + x.disabled}> Radio 3 + + + + x.disabled}> + ${Folder24Filled} + New + + + File + ${Folder24Filled} + + + Workspace + ${Code20Filled} + + + + File + Create + + + + File + ${Folder24Filled} + + + Workspace + ${Code20Filled} + + + + +
+`; + +export default { + title: 'Components/MenuList', + args: { + disabled: false, + }, + argTypes: { + disabled: { + description: 'Disables Menu item', + table: { + defaultValue: { summary: false }, + }, + control: 'boolean', + defaultValue: false, + }, + }, +} as MenuListStoryMeta; + +export const MenuList = renderComponent(storyTemplate).bind({}); + +export const MenuListWithCheckboxSelection = renderComponent(html` +
+ + Item 1 + Item 2 + Item 3 + +
+`); + +export const MenuListWithRadioSelection = renderComponent(html` +
+ + Item 1 + Item 2 + Item 3 + +
+`); + +export const MenuListWithIcons = renderComponent(html` +
+ + Item 1 + + Item 2 + ${Edit20Filled} + + + ${Edit20Filled} + + Item 3 + + +
+`); + +export const MenuListWithIconsAndSelection = renderComponent(html` +
+ + + Item 1 + ${Cut20Filled} + + + Item 2 + ${Edit20Filled} + + Item 3 + +
+`); + +export const MenuListWithSubmenu = renderComponent(html` +
+ + + Item 1 + + Subitem 1 + Subitem 2 + + + + Item 2 + + Subitem 1 + Subitem 1 + + + Item 3 + +
+`); + +export const MenuListWithSubmenuAndIcons = renderComponent(html` +
+ + + Item 1 + ${Edit20Filled} + + + Subitem 1 + ${Folder24Filled} + + + Subitem 2 + ${Code20Filled} + + + + + Item 2 + + + Subitem 1 + ${Folder24Filled} + + + Subitem 1 + ${Code20Filled} + + + + Item 3 + +
+`); + +export const MenuListAligningWithDivider = renderComponent(html` +
+ + Item 1 + Item 2 + + + Item 3 + Item 4 + +
+`); diff --git a/packages/web-components/src/menu-list/menu-list.styles.ts b/packages/web-components/src/menu-list/menu-list.styles.ts new file mode 100644 index 0000000000000..5b3279233faef --- /dev/null +++ b/packages/web-components/src/menu-list/menu-list.styles.ts @@ -0,0 +1,29 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + borderRadiusMedium, + colorNeutralBackground1, + colorTransparentStroke, + shadow16, +} from '../theme/design-tokens.js'; + +/** MenuList styles + * @public + */ +export const styles = css` + ${display('flex')} + + :host { + flex-direction: column; + height: fit-content; + max-width: 300px; + min-width: 160px; + width: auto; + background-color: ${colorNeutralBackground1}; + border: 1px solid ${colorTransparentStroke}; + border-radius: ${borderRadiusMedium}; + box-shadow: ${shadow16}; + padding: 4px; + row-gap: 2px; + } +`; diff --git a/packages/web-components/src/menu-list/menu-list.template.ts b/packages/web-components/src/menu-list/menu-list.template.ts new file mode 100644 index 0000000000000..27d8215c08b7c --- /dev/null +++ b/packages/web-components/src/menu-list/menu-list.template.ts @@ -0,0 +1,5 @@ +import { ElementViewTemplate } from '@microsoft/fast-element'; +import { menuTemplate } from '@microsoft/fast-foundation'; +import type { MenuList } from './menu-list.js'; + +export const template: ElementViewTemplate = menuTemplate(); diff --git a/packages/web-components/src/menu-list/menu-list.ts b/packages/web-components/src/menu-list/menu-list.ts new file mode 100644 index 0000000000000..ebec294fe40e6 --- /dev/null +++ b/packages/web-components/src/menu-list/menu-list.ts @@ -0,0 +1,43 @@ +import { FASTMenu, MenuItemRole } from '@microsoft/fast-foundation'; +import { MenuItem, MenuItemColumnCount } from '../menu-item/index.js'; + +/** + * The base class used for constructing a fluent-menu-list custom element + * @public + */ + +export class MenuList extends FASTMenu { + protected setItems(): void { + super.setItems(); + + /** + * Set the indent attribute on MenuItem elements based on their + * position in the MenuList. Each MenuItem element has a data-indent attribute that is + * used to set the indent of the element's start slot content. + */ + const filteredMenuListItems = this.menuItems?.filter(this.isMenuItemElement); + + filteredMenuListItems?.forEach((item: HTMLElement, index: number) => { + const indent: MenuItemColumnCount = filteredMenuListItems?.reduce((accum, current) => { + const elementValue = MenuList.elementIndent(current as HTMLElement); + + return Math.max(accum, elementValue as number) as MenuItemColumnCount; + }, 0); + + if (item instanceof MenuItem) { + item.setAttribute('data-indent', `${indent}`); + } + }); + } + + private static elementIndent(el: HTMLElement): MenuItemColumnCount { + const role = el.getAttribute('role'); + const startSlot = el.querySelector('[slot=start]'); + + if (role && role !== MenuItemRole.menuitem) { + return startSlot ? 2 : 1; + } + + return startSlot ? 1 : 0; + } +} From 4aad65d6f235023991bccccc08c25c3f31c9c8df Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Fri, 21 Apr 2023 04:19:29 +0000 Subject: [PATCH 083/203] applying package updates --- ...ents-e1aaa3a2-771d-4c16-b8d2-a56deb1fdd28.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) delete mode 100644 change/@fluentui-web-components-e1aaa3a2-771d-4c16-b8d2-a56deb1fdd28.json diff --git a/change/@fluentui-web-components-e1aaa3a2-771d-4c16-b8d2-a56deb1fdd28.json b/change/@fluentui-web-components-e1aaa3a2-771d-4c16-b8d2-a56deb1fdd28.json deleted file mode 100644 index 1772b2b7ad1bf..0000000000000 --- a/change/@fluentui-web-components-e1aaa3a2-771d-4c16-b8d2-a56deb1fdd28.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat(menu-list): Add menu-list and menu-item web components", - "packageName": "@fluentui/web-components", - "email": "brianbrady@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index d8ee5e218fd07..f6e532028fa83 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Fri, 21 Apr 2023 04:19:22 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.19", + "version": "3.0.0-alpha.19", + "comments": { + "prerelease": [ + { + "author": "brianbrady@microsoft.com", + "package": "@fluentui/web-components", + "commit": "f801e34cdc25ba01ccf3b2baa9fac1080d987e9b", + "comment": "feat(menu-list): Add menu-list and menu-item web components" + } + ] + } + }, { "date": "Thu, 20 Apr 2023 04:20:30 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.18", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index 8dcec536d6eca..0cb7d5bb3fcf8 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Thu, 20 Apr 2023 04:20:30 GMT and should not be manually modified. +This log was last generated on Fri, 21 Apr 2023 04:19:22 GMT and should not be manually modified. +## [3.0.0-alpha.19](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.19) + +Fri, 21 Apr 2023 04:19:22 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.18..@fluentui/web-components_v3.0.0-alpha.19) + +### Changes + +- feat(menu-list): Add menu-list and menu-item web components ([PR #26765](https://github.com/microsoft/fluentui/pull/26765) by brianbrady@microsoft.com) + ## [3.0.0-alpha.18](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.18) Thu, 20 Apr 2023 04:20:30 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 996a0464aa901..ac7f56d757151 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.18", + "version": "3.0.0-alpha.19", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From ec275acd0adbf3022e34c6bee6136928b72b4798 Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Fri, 5 May 2023 12:22:45 -0700 Subject: [PATCH 084/203] Adds Radio and RadioGroup as new web components (#27113) * radio init * styles radio * reverts branch * input spec init * cleans up spec * formatting * updates component name to text input * updates component name in spec * radio init * styles radio * adds radio and radio group to index rollup * merge * cherry-pick * fixes arguments passed to slottedRadioButtonsChanged * yarn changew * updates radio group logic * cherry-pick * updates styles * cherry-pick * merge * adds radio group attributes * removes console logs * updates styles * updates RadioGroup readme * fixes jsdoc * updats radio and radio group stories * formats radio group story markup * removes redundant attribute on RadioGroup story * removes dead code * updates radio styles * updates radio group styles * removes redundant attribute on radio group * merge * styles radio and radio group * removes dead code * updates css value to token * exports RadioGroupOrientation namespaced type * updates styles per design review * updates focus styles * reverts file * reverts file * mege * adds back story args * re exports RadioGroupOrientation from FAST * removes redundant stack attribute * testing local tokens for disabled styling * radio: updates styles per review * radio: updates design tokens & styles * radio: adds storybook content * radio init * styles radio * radio: merge * merge * cherry-pick * fixes arguments passed to slottedRadioButtonsChanged * yarn changew * updates radio group logic * cherry-pick * updates styles * cherry-pick * merge * adds radio group attributes * removes console logs * updates styles * updates RadioGroup readme * fixes jsdoc * updats radio and radio group stories * formats radio group story markup * removes redundant attribute on RadioGroup story * removes dead code * updates radio styles * updates radio group styles * removes redundant attribute on radio group * merge * styles radio and radio group * removes dead code * updates css value to token * exports RadioGroupOrientation namespaced type * updates styles per design review * updates focus styles * reverts file * reverts file * mege * adds back story args * re exports RadioGroupOrientation from FAST * removes redundant stack attribute * testing local tokens for disabled styling * radio: updates styles per review * radio: updates design tokens & styles * radio: adds storybook content * radio: initiates css variables in css * leverage css grid for spacing and remove js application for padding * radio: adds export to root json * radio: changes per review * radio: removes pointer events from disabled radio item * radio: updates styling * radio: styles formatting * radio: updates styles * Update change/@fluentui-web-components-94ca1c7a-1462-4aa5-9458-41a54f17527e.json Co-authored-by: Miroslav Stastny * removes redundant style * radio: addresses pr feedback * radio: updates disabled styles * Update packages/web-components/src/radio/radio.stories.ts Co-authored-by: Chris Holt * radio: swaps args table value for const * radio: removes duplicate style * radio: optimizes styles * radio: swaps js for css disabled styling solution * radiogroup, radio: updates based on feedback * radiogroup, radio: updates storybook content and README * radiogroup, radio: updates docs * radiogroup, radio: removes label-position from docs * radiogroup, radio: updates docs * Update packages/web-components/src/radio/README.md Co-authored-by: Miroslav Stastny * radiogroup, radio: addresses feedback * radiogroup, radio: updates docs * radiogroup, radio: addresses feedback * radiogroup, radio: updates styles * radiogroup, radio: removes whitespace * radiogroup, radio: updates styles per review * radiogroup, radio: formats files * radiogroup, radio: format document * radiogroup, radio: fixes import --------- Co-authored-by: Chris Holt Co-authored-by: Miroslav Stastny --- ...-94ca1c7a-1462-4aa5-9458-41a54f17527e.json | 7 + packages/web-components/package.json | 8 + packages/web-components/src/index.ts | 2 + .../web-components/src/radio-group/README.md | 36 +-- .../web-components/src/radio-group/define.ts | 4 + .../web-components/src/radio-group/index.ts | 5 + .../src/radio-group/radio-group.definition.ts | 18 ++ .../src/radio-group/radio-group.stories.ts | 215 ++++++++++++++++++ .../src/radio-group/radio-group.styles.ts | 62 +++++ .../src/radio-group/radio-group.template.ts | 5 + .../src/radio-group/radio-group.ts | 18 ++ packages/web-components/src/radio/README.md | 40 ++-- packages/web-components/src/radio/define.ts | 4 + packages/web-components/src/radio/index.ts | 4 + .../src/radio/radio.definition.ts | 18 ++ .../web-components/src/radio/radio.stories.ts | 63 +++++ .../web-components/src/radio/radio.styles.ts | 130 +++++++++++ .../src/radio/radio.template.ts | 7 + packages/web-components/src/radio/radio.ts | 7 + 19 files changed, 616 insertions(+), 37 deletions(-) create mode 100644 change/@fluentui-web-components-94ca1c7a-1462-4aa5-9458-41a54f17527e.json create mode 100644 packages/web-components/src/radio-group/define.ts create mode 100644 packages/web-components/src/radio-group/index.ts create mode 100644 packages/web-components/src/radio-group/radio-group.definition.ts create mode 100644 packages/web-components/src/radio-group/radio-group.stories.ts create mode 100644 packages/web-components/src/radio-group/radio-group.styles.ts create mode 100644 packages/web-components/src/radio-group/radio-group.template.ts create mode 100644 packages/web-components/src/radio-group/radio-group.ts create mode 100644 packages/web-components/src/radio/define.ts create mode 100644 packages/web-components/src/radio/index.ts create mode 100644 packages/web-components/src/radio/radio.definition.ts create mode 100644 packages/web-components/src/radio/radio.stories.ts create mode 100644 packages/web-components/src/radio/radio.styles.ts create mode 100644 packages/web-components/src/radio/radio.template.ts create mode 100644 packages/web-components/src/radio/radio.ts diff --git a/change/@fluentui-web-components-94ca1c7a-1462-4aa5-9458-41a54f17527e.json b/change/@fluentui-web-components-94ca1c7a-1462-4aa5-9458-41a54f17527e.json new file mode 100644 index 0000000000000..35fa050bf1d10 --- /dev/null +++ b/change/@fluentui-web-components-94ca1c7a-1462-4aa5-9458-41a54f17527e.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat(radio): add radio and radio-group web components", + "packageName": "@fluentui/web-components", + "email": "brianbrady@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index ac7f56d757151..c3280bf1a5e52 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -84,6 +84,14 @@ "types": "./dist/esm/progress-bar/define.d.ts", "default": "./dist/esm/progress-bar/define.js" }, + "./radio": { + "types": "./dist/esm/radio/define.d.ts", + "default": "./dist/esm/radio/define.js" + }, + "./radio-group": { + "types": "./dist/esm/radio-group/define.d.ts", + "default": "./dist/esm/radio-group/define.js" + }, "./slider": { "types": "./dist/esm/slider/define.d.ts", "default": "./dist/esm/slider/define.js" diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index cfbb551238a38..5207274c04684 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -13,6 +13,8 @@ export * from './menu-button/index.js'; export * from './menu-item/index.js'; export * from './menu-list/index.js'; export * from './progress-bar/index.js'; +export * from './radio/index.js'; +export * from './radio-group/index.js'; export * from './slider/index.js'; export * from './spinner/index.js'; export * from './switch/index.js'; diff --git a/packages/web-components/src/radio-group/README.md b/packages/web-components/src/radio-group/README.md index d80d1ab434f63..b94bc67efda97 100644 --- a/packages/web-components/src/radio-group/README.md +++ b/packages/web-components/src/radio-group/README.md @@ -1,6 +1,6 @@ # Radio Group -> RadioGroup lets people select a single option from two or more Radio items. Use RadioGroup to present all available choices if there's enough space.. +> RadioGroup lets users select a single option from two or more Radio items. Use RadioGroup to present all available choices if there's enough space..
@@ -36,13 +36,14 @@ Used anywhere an author might group a list of radio options. ### **Fields** -| Name | Privacy | Type | Default | Description | -| ------------- | ------- | ------------------------ | ------------ | ----------------------------------------------------------------------------------------------------- | -| `disabled` | public | `boolean` | `false` | Disables the radio group and child radios. | -| `name` | public | `string` | | The name of the radio group. Setting this value will set the name value for all child radio elements. | -| `value` | public | `string` | | The value of the checked radio. | -| `orientation` | public | `horizontal \| vertical` | `horizontal` | The orientation of the group | -| default slot | public | `HTMLElement[]` | | The default slot expecting Radio items | +| Name | Privacy | Type | Default | Description | +| ------------- | ------- | ------------------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `disabled` | public | `boolean` | `false` | Disables the radio group and child radios. | +| `name` | public | `string` | | The name of the radio group. Setting this value will set the name value for all child radio elements. | +| `value` | public | `string` | | The value of the checked radio. | +| `orientation` | public | `horizontal \| vertical` | `horizontal` | Determines whether radios in a radio group are rendered in a horizontal row or a vertical column. The default value is horizontal, which will render radios in a horizontal row with labels appearing inline. Setting orientation to vertical will render radios in a vertical column with labels appearing inline. | +| `stacked` | public | `boolean` | `false` | Determines whether the labels for radios appear inline or stacked when orientation is set to horizontal. The default value is false, which will display the labels inline. If stacked is set to true, the labels will appear under each radio in a horizontal row. | +| default slot | public | `HTMLElement[]` | | The default slot expecting Radio items. |
@@ -57,9 +58,9 @@ Used anywhere an author might group a list of radio options. ### **Events** -| Name | Type | Description | -| -------- | ---- | ---------------------------------------------------- | -| `change` | | Fires a custom 'change' event when the value changes | +| Name | Event Type | Target | Arguments | Description | +| -------- | ------------- | ---------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | +| `change` | `CustomEvent` | `FASTRadioGroup` | none | Fired when the value of the RadioGroup changes (i.e., when a different radio button within the group is selected) |
@@ -97,9 +98,10 @@ Used anywhere an author might group a list of radio options. ### **WAI-ARIA Roles, States, and Properties** -| Attributes | value | Description | -| ----------------- | ----- | ---------------------------------------- | -| `aria-labelledby` | | used to associate a label with the group | +| Attributes | value | Description | +| ----------------- | -------------- | ---------------------------------------- | +| `aria-labelledby` | | used to associate a label with the group | +| `role` | `"radiogroup"` | used to define a group of radio buttons |

@@ -122,6 +124,6 @@ Used anywhere an author might group a list of radio options.
**Property Mapping** -| Fluent UI React 9 | Fluent Web Components 3 | Description of difference | -|-------------------|------------------------ |---------------------------| -| `layout` | `orientation` | React implementation requires user to pass either `"horizontal"` or `"horizontal-stacked"` through `layout` prop.
WC3 implementation requires user to either pass `"vertical"` or "`horizontal"` through `orientation` attribute. +| Fluent UI React 9 | Fluent Web Components | Description of difference | +|-------------------|-------------------------- |---------------------------| +| `layout` | `orientation` + `stacked` | React implementation requires user to pass either `"horizontal"` or `"horizontal-stacked"` through `layout` prop.
WC3 implementation requires user to either pass `"vertical"` or "`horizontal"` through `orientation` attribute. Additionally, adding the `boolean` attribute `stacked` when the orientation is set to `horizontal` will create the `horizontal-stacked` layout available in FUIR9. diff --git a/packages/web-components/src/radio-group/define.ts b/packages/web-components/src/radio-group/define.ts new file mode 100644 index 0000000000000..2da64783f8341 --- /dev/null +++ b/packages/web-components/src/radio-group/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './radio-group.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/radio-group/index.ts b/packages/web-components/src/radio-group/index.ts new file mode 100644 index 0000000000000..cfc435af8a753 --- /dev/null +++ b/packages/web-components/src/radio-group/index.ts @@ -0,0 +1,5 @@ +export * from './radio-group.js'; +export { definition as RadioGroupDefinition } from './radio-group.definition.js'; +export { styles as RadioGroupStyles } from './radio-group.styles.js'; +export { template as RadioGroupTemplate } from './radio-group.template.js'; +export { RadioGroupOrientation } from '@microsoft/fast-foundation'; diff --git a/packages/web-components/src/radio-group/radio-group.definition.ts b/packages/web-components/src/radio-group/radio-group.definition.ts new file mode 100644 index 0000000000000..0e3f17541c84b --- /dev/null +++ b/packages/web-components/src/radio-group/radio-group.definition.ts @@ -0,0 +1,18 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { RadioGroup } from './radio-group.js'; +import { styles } from './radio-group.styles.js'; +import { template } from './radio-group.template.js'; + +/** + * The Fluent RadioGroup Element. + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = RadioGroup.compose({ + name: `${FluentDesignSystem.prefix}-radio-group`, + template, + styles, +}); diff --git a/packages/web-components/src/radio-group/radio-group.stories.ts b/packages/web-components/src/radio-group/radio-group.stories.ts new file mode 100644 index 0000000000000..33d1eb816a954 --- /dev/null +++ b/packages/web-components/src/radio-group/radio-group.stories.ts @@ -0,0 +1,215 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { RadioGroupOrientation } from '@microsoft/fast-foundation'; +import { renderComponent } from '../helpers.stories.js'; +import { RadioGroup as FluentRadioGroup } from './radio-group.js'; +import './define.js'; +import '../radio/define.js'; + +type RadioGroupStoryArgs = Args & FluentRadioGroup; +type RadioGroupStoryMeta = Meta; + +const storyTemplate = html` + x.disabled} + ?stacked=${x => x.stacked} + orientation=${x => x.orientation} + name="radio-story" + > + Favorite Fruit + Apple + Pear + Banana + Orange + +`; + +export default { + title: 'Components/RadioGroup', + args: { + disabled: false, + orientation: RadioGroupOrientation.horizontal, + }, + argTypes: { + disabled: { + control: { + type: 'boolean', + }, + table: { + type: { + summary: 'Sets disabled state on radio', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + checked: { + control: { + type: 'boolean', + }, + table: { + type: { + summary: 'Sets checked state on radio', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + stacked: { + control: { + type: 'boolean', + }, + table: { + type: { + summary: 'Creates a stacked layout for horizontal radio buttons', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + orientation: { + control: { + type: 'select', + options: Object.values(RadioGroupOrientation), + }, + defaultValue: RadioGroupOrientation.horizontal, + table: { + type: { + summary: 'Sets orientation of radio group', + }, + defaultValue: { + summary: RadioGroupOrientation.horizontal, + }, + }, + }, + change: { + action: 'change', + table: { + type: { + summary: 'Event that is fired when the selected radio button changes', + }, + defaultValue: { + summary: null, + }, + }, + }, + }, +} as RadioGroupStoryMeta; + +export const RadioGroup = renderComponent(storyTemplate).bind({}); + +export const RadioGroupLabelledby = renderComponent(html` + + Favorite Fruit + Apple + Pear + Banana + Orange + +`); + +export const RadioGroupLayoutVertical = renderComponent(html` + + Favorite Fruit + Apple + Pear + Banana + Orange + +`); + +export const RadioGroupLayoutHorizontal = renderComponent(html` + + Favorite Fruit + Apple + Pear + Banana + Orange + +`); + +export const RadioGroupLayoutHorizontalStacked = renderComponent(html` + + Favorite Fruit + Apple + Pear + Banana + Orange + +`); + +export const RadioGroupDefaultChecked = renderComponent(html` + + Favorite Fruit + Apple + Pear + Banana + Orange + +`); + +export const RadioGroupDisabled = renderComponent(html` + + Favorite Fruit + Apple + Pear + Banana + Orange + +`); + +export const RadioGroupDisabledItem = renderComponent(html` + + Favorite Fruit + Apple + Pear + Banana + Orange + +`); + +const getLabelContent = (): string | undefined => { + const radioGroup = document.querySelector('#radio-group-fruit') as FluentRadioGroup; + + if (!radioGroup) return; // add a check to make sure radioGroup exists + + const selectedRadio = radioGroup.value as string; + + if (selectedRadio) { + return `Favorite fruit: ${selectedRadio.charAt(0).toUpperCase() + selectedRadio.slice(1)}`; + } else { + return 'Please select your favorite fruit'; + } +}; + +const handleChange = (event: CustomEvent) => { + const radioGroup = document.querySelector('#radio-group-fruit') as FluentRadioGroup; + + if (!radioGroup) return; // add a check to make sure radioGroup exists + + const selectedRadio = radioGroup.value as string; + const labelElement = radioGroup.querySelector('[slot="label"]') as HTMLSpanElement; + if (selectedRadio) { + const labelContent = selectedRadio.charAt(0).toUpperCase() + selectedRadio.slice(1); + labelElement.textContent = `Favorite fruit: ${labelContent}`; + } +}; + +export const RadioGroupChangeEvent = renderComponent(html` + + ${getLabelContent} + Apple + Pear + Banana + Orange + +`); diff --git a/packages/web-components/src/radio-group/radio-group.styles.ts b/packages/web-components/src/radio-group/radio-group.styles.ts new file mode 100644 index 0000000000000..ec203c42a9a6e --- /dev/null +++ b/packages/web-components/src/radio-group/radio-group.styles.ts @@ -0,0 +1,62 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + colorNeutralForeground1, + colorNeutralForegroundDisabled, + fontFamilyBase, + fontSizeBase300, + fontWeightRegular, + lineHeightBase300, + spacingHorizontalS, + spacingHorizontalXS, + spacingVerticalS, +} from '../theme/design-tokens.js'; + +/** RadioGroup styles + * @public + */ +export const styles = css` + ${display('flex')} + + :host { + align-items: flex-start; + flex-direction: column; + row-gap: ${spacingVerticalS}; + } + :host([disabled]) ::slotted([role='radio']) { + --control-border-color: ${colorNeutralForegroundDisabled}; + --checked-indicator-background-color: ${colorNeutralForegroundDisabled}; + --state-color: ${colorNeutralForegroundDisabled}; + } + ::slotted([slot='label']) { + color: ${colorNeutralForeground1}; + padding: ${spacingVerticalS} ${spacingHorizontalS} ${spacingVerticalS} ${spacingHorizontalXS}; + font: ${fontWeightRegular} ${fontSizeBase300} / ${lineHeightBase300} ${fontFamilyBase}; + cursor: default; + } + .positioning-region { + display: flex; + flex-wrap: wrap; + } + :host([orientation='vertical']) .positioning-region { + flex-direction: column; + justify-content: flex-start; + } + :host([orientation='horizontal']) .positioning-region { + flex-direction: row; + } + :host([orientation='horizontal']) ::slotted([role='radio']) { + padding-inline-end: ${spacingHorizontalS}; + } + :host([orientation='horizontal'][stacked]) ::slotted([role='radio']) { + display: flex; + flex-direction: column; + padding-inline: ${spacingHorizontalS}; + height: auto; + align-items: center; + justify-content: center; + } + :host([disabled]) ::slotted([role='radio']) { + pointer-events: none; + } +`; diff --git a/packages/web-components/src/radio-group/radio-group.template.ts b/packages/web-components/src/radio-group/radio-group.template.ts new file mode 100644 index 0000000000000..5f884fd9e4c3b --- /dev/null +++ b/packages/web-components/src/radio-group/radio-group.template.ts @@ -0,0 +1,5 @@ +import type { ElementViewTemplate } from '@microsoft/fast-element'; +import { radioGroupTemplate } from '@microsoft/fast-foundation'; +import type { RadioGroup } from './radio-group.js'; + +export const template: ElementViewTemplate = radioGroupTemplate(); diff --git a/packages/web-components/src/radio-group/radio-group.ts b/packages/web-components/src/radio-group/radio-group.ts new file mode 100644 index 0000000000000..7ad958af22283 --- /dev/null +++ b/packages/web-components/src/radio-group/radio-group.ts @@ -0,0 +1,18 @@ +import { attr } from '@microsoft/fast-element'; +import { FASTRadioGroup } from '@microsoft/fast-foundation'; + +/** + * The base class used for constructing a fluent-radio-group custom element + * @public + */ +export class RadioGroup extends FASTRadioGroup { + /** + * sets radio layout styles + * + * @public + * @remarks + * HTML Attribute: stacked + */ + @attr({ mode: 'boolean' }) + public stacked: boolean = false; +} diff --git a/packages/web-components/src/radio/README.md b/packages/web-components/src/radio/README.md index 10152def1bbc1..9193cfb46909a 100644 --- a/packages/web-components/src/radio/README.md +++ b/packages/web-components/src/radio/README.md @@ -38,12 +38,11 @@ Used anywhere an author might otherwise use an input[type="radio"]. Used to faci ### **Fields** -| Name | Privacy | Type | Default | Description | -| --------------- | ------- | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| `name` | public | `string` | | The name of the radio. See [name attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefname) for more info. | -| `disabled` | public | `boolean` | | Sets disabled state for radio | -| `labelPosition` | public | `"after"` `"below"` | `"below"` | The position of the label relative to the radio indicator. | -| `checked` | public | `boolean` | `false` | When true, radio button will be checked | +| Name | Privacy | Type | Default | Description | +| ---------- | ------- | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | public | `string` | | The name of the radio. See [name attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefname) for more info. When the `radio` component is rendered inside a `radio-group`, the `radio-group` overwrites the `name` in all its `radio` components. | +| `disabled` | public | `boolean` | | Sets disabled state for radio | +| `checked` | public | `boolean` | `false` | When true, radio button will be checked |
@@ -51,22 +50,13 @@ Used anywhere an author might otherwise use an input[type="radio"]. Used to faci
-### **Events** - -| Name | Type | Inherited From | -| -------- | ---- | -------------- | -| `change` | | | - -
- ### **Attributes** -| Name | Field | -| ---------------- | ------------- | -| `name` | name | -| `disabled` | disabled | -| `label-position` | labelPosition | -| `checked` | checked | +| Name | Field | +| ---------- | -------- | +| `name` | name | +| `disabled` | disabled | +| `checked` | checked |
@@ -117,6 +107,16 @@ Used anywhere an author might otherwise use an input[type="radio"]. Used to faci ### **Fluent Web Component v3 v.s Fluent React 9** +**Deltas** + +In contrast to the FUIRv9 implimentation of the `Radio` component the WC3 `Radio` must be rendered inside the WC3 `RadioGroup` to inherit all appropriate styles. + +```html + + + +``` +
**Component and Slot Mapping** diff --git a/packages/web-components/src/radio/define.ts b/packages/web-components/src/radio/define.ts new file mode 100644 index 0000000000000..66ca2a55ac25b --- /dev/null +++ b/packages/web-components/src/radio/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './radio.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/radio/index.ts b/packages/web-components/src/radio/index.ts new file mode 100644 index 0000000000000..e1af0f69389a1 --- /dev/null +++ b/packages/web-components/src/radio/index.ts @@ -0,0 +1,4 @@ +export * from './radio.js'; +export { definition as RadioDefinition } from './radio.definition.js'; +export { styles as RadioStyles } from './radio.styles.js'; +export { template as RadioTemplate } from './radio.template.js'; diff --git a/packages/web-components/src/radio/radio.definition.ts b/packages/web-components/src/radio/radio.definition.ts new file mode 100644 index 0000000000000..479c8c1bb37c0 --- /dev/null +++ b/packages/web-components/src/radio/radio.definition.ts @@ -0,0 +1,18 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Radio } from './radio.js'; +import { styles } from './radio.styles.js'; +import { template } from './radio.template.js'; + +/** + * The Fluent Radio Element. + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = Radio.compose({ + name: `${FluentDesignSystem.prefix}-radio`, + template, + styles, +}); diff --git a/packages/web-components/src/radio/radio.stories.ts b/packages/web-components/src/radio/radio.stories.ts new file mode 100644 index 0000000000000..52afdf568c0f2 --- /dev/null +++ b/packages/web-components/src/radio/radio.stories.ts @@ -0,0 +1,63 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../helpers.stories.js'; +import type { Radio as FluentRadio } from './radio.js'; +import './define.js'; +import '../radio-group/define.js'; + +type RadioStoryArgs = Args & FluentRadio; +type RadioStoryMeta = Meta; + +const storyTemplate = html` +
+ Option 1 +
+`; + +export default { + title: 'Components/Radio', + args: { + checked: false, + disabled: false, + }, + argTypes: { + checked: { + control: { + type: 'boolean', + }, + table: { + type: { + summary: 'Sets checked state on radio', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + disabled: { + control: { + type: 'boolean', + }, + table: { + type: { + summary: 'Sets disabled state on radio', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + }, +} as RadioStoryMeta; + +export const Radio = renderComponent(storyTemplate).bind({}); + +export const Checked = renderComponent(html` + Apple +`); + +export const Disabled = renderComponent(html` + Apple +`); diff --git a/packages/web-components/src/radio/radio.styles.ts b/packages/web-components/src/radio/radio.styles.ts new file mode 100644 index 0000000000000..d80095a189410 --- /dev/null +++ b/packages/web-components/src/radio/radio.styles.ts @@ -0,0 +1,130 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + borderRadiusCircular, + borderRadiusSmall, + colorCompoundBrandForeground1, + colorCompoundBrandForeground1Pressed, + colorCompoundBrandStrokeHover, + colorCompoundBrandStrokePressed, + colorNeutralForeground2, + colorNeutralForeground3, + colorNeutralForegroundDisabled, + colorNeutralStrokeAccessible, + colorNeutralStrokeAccessibleHover, + colorNeutralStrokeAccessiblePressed, + colorStrokeFocus1, + colorStrokeFocus2, + fontFamilyBase, + fontSizeBase300, + fontWeightRegular, + lineHeightBase300, + spacingHorizontalS, + spacingHorizontalXS, + spacingVerticalS, +} from '../theme/design-tokens.js'; + +/** Radio styles + * @public + */ +export const styles = css` + ${display('inline-grid')} + + :host { + grid-auto-flow: column; + grid-template-columns: max-content; + gap: ${spacingHorizontalXS}; + align-items: center; + height: 32px; + cursor: pointer; + outline: none; + position: relative; + user-select: none; + color: blue; + color: var(--state-color, ${colorNeutralForeground3}); + padding-inline-end: ${spacingHorizontalS}; + --control-border-color: ${colorNeutralStrokeAccessible}; + --checked-indicator-background-color: ${colorCompoundBrandForeground1}; + --state-color: ${colorNeutralForeground3}; + } + :host([disabled]) { + --control-border-color: ${colorNeutralForegroundDisabled}; + --checked-indicator-background-color: ${colorNeutralForegroundDisabled}; + --state-color: ${colorNeutralForegroundDisabled}; + } + .label { + cursor: pointer; + font-family: ${fontFamilyBase}; + font-size: ${fontSizeBase300}; + font-weight: ${fontWeightRegular}; + line-height: ${lineHeightBase300}; + } + .label__hidden { + display: none; + } + .control { + box-sizing: border-box; + align-items: center; + border: 1px solid var(--control-border-color, ${colorNeutralStrokeAccessible}); + border-radius: ${borderRadiusCircular}; + display: flex; + height: 16px; + justify-content: center; + margin: ${spacingVerticalS} ${spacingHorizontalS}; + position: relative; + width: 16px; + justify-self: center; + } + .checked-indicator { + border-radius: ${borderRadiusCircular}; + height: 10px; + opacity: 0; + width: 10px; + } + :host([aria-checked='false']:hover) .control { + color: ${colorNeutralForeground2}; + } + :host(:focus-visible) { + border-radius: ${borderRadiusSmall}; + box-shadow: 0 0 0 3px ${colorStrokeFocus2}; + outline: 1px solid ${colorStrokeFocus1}; + } + :host(:hover) .control { + border-color: ${colorNeutralStrokeAccessibleHover}; + } + :host(:active) .control { + border-color: ${colorNeutralStrokeAccessiblePressed}; + } + :host([aria-checked='true']) .checked-indicator { + opacity: 1; + } + :host([aria-checked='true']) .control { + border-color: var(--control-border-color, ${colorNeutralStrokeAccessible}); + } + :host([aria-checked='true']) .checked-indicator { + background-color: var(--checked-indicator-background-color, ${colorCompoundBrandForeground1}); + } + :host([aria-checked='true']:hover) .control { + border-color: ${colorCompoundBrandStrokeHover}; + } + :host([aria-checked='true']:hover) .checked-indicator { + background-color: ${colorCompoundBrandStrokeHover}; + } + :host([aria-checked='true']:active) .control { + border-color: ${colorCompoundBrandStrokePressed}; + } + :host([aria-checked='true']:active) .checked-indicator { + background: ${colorCompoundBrandForeground1Pressed}; + } + :host([disabled]) { + color: ${colorNeutralForegroundDisabled}; + pointer-events: none; + } + :host([disabled]) .control { + pointer-events: none; + border-color: ${colorNeutralForegroundDisabled}; + } + :host([disabled]) .checked-indicator { + background: ${colorNeutralForegroundDisabled}; + } +`; diff --git a/packages/web-components/src/radio/radio.template.ts b/packages/web-components/src/radio/radio.template.ts new file mode 100644 index 0000000000000..5c387758c6670 --- /dev/null +++ b/packages/web-components/src/radio/radio.template.ts @@ -0,0 +1,7 @@ +import { ElementViewTemplate, html } from '@microsoft/fast-element'; +import { radioTemplate } from '@microsoft/fast-foundation'; +import type { Radio } from './radio.js'; + +export const template: ElementViewTemplate = radioTemplate({ + checkedIndicator: html`
`, +}); diff --git a/packages/web-components/src/radio/radio.ts b/packages/web-components/src/radio/radio.ts new file mode 100644 index 0000000000000..56c36b4198b26 --- /dev/null +++ b/packages/web-components/src/radio/radio.ts @@ -0,0 +1,7 @@ +import { FASTRadio } from '@microsoft/fast-foundation'; + +/** + * The base class used for constructing a fluent-radio custom element + * @public + */ +export class Radio extends FASTRadio {} From e866eafdccc69d0142d7f8adfb38d85defd958b7 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Mon, 8 May 2023 04:20:04 +0000 Subject: [PATCH 085/203] applying package updates --- ...ents-94ca1c7a-1462-4aa5-9458-41a54f17527e.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) delete mode 100644 change/@fluentui-web-components-94ca1c7a-1462-4aa5-9458-41a54f17527e.json diff --git a/change/@fluentui-web-components-94ca1c7a-1462-4aa5-9458-41a54f17527e.json b/change/@fluentui-web-components-94ca1c7a-1462-4aa5-9458-41a54f17527e.json deleted file mode 100644 index 35fa050bf1d10..0000000000000 --- a/change/@fluentui-web-components-94ca1c7a-1462-4aa5-9458-41a54f17527e.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat(radio): add radio and radio-group web components", - "packageName": "@fluentui/web-components", - "email": "brianbrady@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index f6e532028fa83..9c881b52dfb56 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Mon, 08 May 2023 04:19:58 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.20", + "version": "3.0.0-alpha.20", + "comments": { + "prerelease": [ + { + "author": "brianbrady@microsoft.com", + "package": "@fluentui/web-components", + "commit": "1dddc623661d1b2667a866a1f779363d91a759e4", + "comment": "feat(radio): add radio and radio-group web components" + } + ] + } + }, { "date": "Fri, 21 Apr 2023 04:19:22 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.19", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index 0cb7d5bb3fcf8..6708289d0b035 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Fri, 21 Apr 2023 04:19:22 GMT and should not be manually modified. +This log was last generated on Mon, 08 May 2023 04:19:58 GMT and should not be manually modified. +## [3.0.0-alpha.20](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.20) + +Mon, 08 May 2023 04:19:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.19..@fluentui/web-components_v3.0.0-alpha.20) + +### Changes + +- feat(radio): add radio and radio-group web components ([PR #27113](https://github.com/microsoft/fluentui/pull/27113) by brianbrady@microsoft.com) + ## [3.0.0-alpha.19](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.19) Fri, 21 Apr 2023 04:19:22 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index c3280bf1a5e52..8f375641b7d8c 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", "sideEffects": false, - "version": "3.0.0-alpha.19", + "version": "3.0.0-alpha.20", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 1240c12bfaef983324c32f6bb9763da487d6856a Mon Sep 17 00:00:00 2001 From: Ryan Merrill Date: Fri, 12 May 2023 14:52:05 -0400 Subject: [PATCH 086/203] Adds components to api report for importing into wrappers (#27822) --- packages/web-components/docs/api-report.md | 435 +++++++++++++++++++++ 1 file changed, 435 insertions(+) diff --git a/packages/web-components/docs/api-report.md b/packages/web-components/docs/api-report.md index f1da965703c52..7124ab8142dab 100644 --- a/packages/web-components/docs/api-report.md +++ b/packages/web-components/docs/api-report.md @@ -4,6 +4,8 @@ ```ts +import { AnchorOptions as AnchorButtonOptions } from '@microsoft/fast-foundation'; +import { ButtonOptions } from '@microsoft/fast-foundation'; import { CSSDesignToken } from '@microsoft/fast-foundation'; import { DividerOrientation } from '@microsoft/fast-foundation'; import { DividerRole } from '@microsoft/fast-foundation'; @@ -11,17 +13,28 @@ import { ElementStyles } from '@microsoft/fast-element'; import { ElementViewTemplate } from '@microsoft/fast-element'; import { FASTAccordion } from '@microsoft/fast-foundation'; import { FASTAccordionItem } from '@microsoft/fast-foundation'; +import { FASTAnchor } from '@microsoft/fast-foundation'; +import { FASTButton } from '@microsoft/fast-foundation'; import { FASTDivider } from '@microsoft/fast-foundation'; import { FASTElement } from '@microsoft/fast-element'; import { FASTElementDefinition } from '@microsoft/fast-element'; +import { FASTMenu } from '@microsoft/fast-foundation'; +import { FASTMenuItem } from '@microsoft/fast-foundation'; import { FASTProgress } from '@microsoft/fast-foundation'; import { FASTProgressRing } from '@microsoft/fast-foundation'; +import { FASTRadio } from '@microsoft/fast-foundation'; +import { FASTRadioGroup } from '@microsoft/fast-foundation'; import { FASTSlider } from '@microsoft/fast-foundation'; import { FASTSwitch } from '@microsoft/fast-foundation'; +import { FASTTab } from '@microsoft/fast-foundation'; +import { FASTTabPanel } from '@microsoft/fast-foundation'; +import { FASTTabs } from '@microsoft/fast-foundation'; +import { RadioGroupOrientation } from '@microsoft/fast-foundation'; import { SliderOrientation } from '@microsoft/fast-foundation'; import { StartEnd } from '@microsoft/fast-foundation'; import { StartEndOptions } from '@microsoft/fast-foundation'; import { StaticallyComposableHTML } from '@microsoft/fast-foundation'; +import { TabsOrientation } from '@microsoft/fast-foundation'; import type { Theme } from '@fluentui/tokens'; import { ValuesOf } from '@microsoft/fast-foundation'; @@ -83,6 +96,64 @@ export const accordionStyles: ElementStyles; // @public (undocumented) export const accordionTemplate: ElementViewTemplate; +// @public +export class AnchorButton extends FASTAnchor { + appearance?: AnchorButtonAppearance | undefined; + // (undocumented) + connectedCallback(): void; + disabled?: boolean; + // (undocumented) + protected disabledChanged(prev: boolean, next: boolean): void; + disabledFocusable?: boolean; + // (undocumented) + protected disabledFocusableChanged(prev: boolean, next: boolean): void; + // (undocumented) + disconnectedCallback(): void; + iconOnly: boolean; + shape?: AnchorButtonShape | undefined; + size?: AnchorButtonSize; +} + +// @public +export const AnchorButtonAppearance: { + readonly primary: "primary"; + readonly outline: "outline"; + readonly subtle: "subtle"; + readonly secondary: "secondary"; + readonly transparent: "transparent"; +}; + +// @public +export type AnchorButtonAppearance = ValuesOf; + +// @public +export const AnchorButtonDefinition: FASTElementDefinition; + +export { AnchorButtonOptions } + +// @public +export const AnchorButtonShape: { + readonly circular: "circular"; + readonly rounded: "rounded"; + readonly square: "square"; +}; + +// @public +export type AnchorButtonShape = ValuesOf; + +// @public +export const AnchorButtonSize: { + readonly small: "small"; + readonly medium: "medium"; + readonly large: "large"; +}; + +// @public +export type AnchorButtonSize = ValuesOf; + +// @public +export const AnchorButtonTemplate: ElementViewTemplate; + // @public export class Avatar extends FASTElement { active?: AvatarActive | undefined; @@ -332,6 +403,64 @@ export const borderRadiusSmall: CSSDesignToken; // @public (undocumented) export const borderRadiusXLarge: CSSDesignToken; +// @public +export class Button extends FASTButton { + appearance?: ButtonAppearance | undefined; + // (undocumented) + connectedCallback(): void; + disabledFocusable?: boolean; + // (undocumented) + protected disabledFocusableChanged(prev: boolean, next: boolean): void; + // (undocumented) + disconnectedCallback(): void; + iconOnly: boolean; + shape?: ButtonShape | undefined; + size?: ButtonSize; +} + +// @public +export const ButtonAppearance: { + readonly primary: "primary"; + readonly outline: "outline"; + readonly subtle: "subtle"; + readonly secondary: "secondary"; + readonly transparent: "transparent"; +}; + +// @public +export type ButtonAppearance = ValuesOf; + +// @public +export const ButtonDefinition: FASTElementDefinition; + +export { ButtonOptions } +export { ButtonOptions as CompoundButtonOptions } +export { ButtonOptions as MenuButtonOptions } +export { ButtonOptions as ToggleButtonOptions } + +// @public +export const ButtonShape: { + readonly circular: "circular"; + readonly rounded: "rounded"; + readonly square: "square"; +}; + +// @public +export type ButtonShape = ValuesOf; + +// @public +export const ButtonSize: { + readonly small: "small"; + readonly medium: "medium"; + readonly large: "large"; +}; + +// @public +export type ButtonSize = ValuesOf; + +// @public +export const ButtonTemplate: ElementViewTemplate + + + + + + + `; + }); + + const isDisabled = await element.evaluate((node: Element) => node.hasAttribute('disabled')); + expect(isDisabled).toBe(true); + + await first.focus(); + + await expect(first).toBeFocused(); + + await first.press('Tab'); + + await expect(second).toBeFocused(); + + expect(await element.evaluate(node => node.getAttribute('tabindex') === '-1')).toBeTruthy(); + }); + + test('should NOT be focusable via click when disabled', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + + + + + + `; + }); + + const radios = page.locator('fluent-radio'); + const radioItemsCount = await radios.count(); + const button = page.locator('button', { hasText: 'Button' }); + + await button.focus(); + await expect(button).toBeFocused(); + + for (let i = 0; i < radioItemsCount; i++) { + const item = radios.nth(i); + await item.click(); + await expect(item).toBeFocused(); + } + + const element = page.locator('fluent-radio-group'); + await element.evaluate(node => node.setAttribute('disabled', '')); + + const isDisabled = await element.evaluate((node: Element) => node.hasAttribute('disabled')); + await expect(isDisabled).toBe(true); + + for (let i = 0; i < radioItemsCount; i++) { + const item = radios.nth(i); + + // Using page.evaluate to manually simulate what would happen with a click event + const isClickable = await page.evaluate(el => { + const event = new MouseEvent('click', { + bubbles: true, + cancelable: true, + view: window, + }); + + // The return value of dispatchEvent will be false if any event listener called preventDefault, or true otherwise. + return el?.dispatchEvent(event); + }, await item.elementHandle()); + + // Since the radio group is disabled, the click event should be canceled, so we expect isClickable to be false + await expect(isClickable).toBe(false); + } + }); + test('should set tabindex of 0 to a child radio with a matching `value`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + + + + + `; + }); + + await expect(radios.nth(0)).toHaveAttribute('tabindex', '0'); + }); + + test('should NOT set `tabindex` of 0 to a child radio if its value does not match the radiogroup `value`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + + + + + `; + }); + + expect( + await radios.evaluateAll(radios => radios.every(radio => radio.getAttribute('tabindex') === '-1')), + ).toBeTruthy(); + }); + + test('should set a child radio with a matching `value` to `checked`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + + + + + `; + }); + + await expect(radios.nth(0)).not.toBeChecked(); + + await expect(radios.nth(1)).toBeChecked(); + + await expect(radios.nth(2)).not.toBeChecked(); + }); + + test('should set a child radio with a matching `value` to `checked` when value changes', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + + + + + `; + }); + + await element.evaluate((node: RadioGroup) => { + node.value = 'bar'; + }); + + await expect(radios.nth(0)).not.toBeChecked(); + + await expect(radios.nth(1)).toBeChecked(); + + await expect(radios.nth(2)).not.toBeChecked(); + }); + + test('should mark only the last radio defaulted to checked as checked', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + + + + + `; + }); + + expect(await radios.evaluateAll(radios => radios.filter(radio => radio.checked).length)).toBe(1); + + await expect(radios.nth(0)).not.toBeChecked(); + + await expect(radios.nth(1)).not.toBeChecked(); + + await expect(radios.nth(2)).toBeChecked(); + }); + + test('should mark radio matching value on radio-group over any checked attributes', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + + + + + `; + }); + + expect(await radios.evaluateAll(radios => radios.filter(radio => radio.checked).length)).toBe(1); + + await expect(radios.nth(0)).toBeChecked(); + + await expect(radios.nth(1)).not.toBeChecked(); + + // radio-group explicitly sets non-matching radio's checked to false if + // a value match was found, but the attribute should still persist. + expect(await radios.nth(1).evaluate(node => node.hasAttribute('checked'))).toBeTruthy(); + + await expect(radios.nth(2)).not.toBeChecked(); + }); + + test('should allow resetting of elements by the parent form', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` +
+ + + + + +
+ `; + }); + + const form = page.locator('form'); + + await radios.nth(2).evaluate(node => { + node.checked = true; + }); + + await expect(radios.nth(0)).not.toBeChecked(); + + await expect(radios.nth(1)).not.toBeChecked(); + + await expect(radios.nth(2)).toBeChecked(); + + await form.evaluate(node => { + node.reset(); + }); + + await expect(radios.nth(0)).not.toBeChecked(); + + await expect(radios.nth(1)).toBeChecked(); + + await expect(radios.nth(2)).not.toBeChecked(); + }); +}); From d4cf0829f8c36a6a8b1a9b723089559a2e744093 Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Tue, 22 Aug 2023 10:57:29 -0700 Subject: [PATCH 144/203] Text component unit tests (#28834) * radio init * styles radio * reverts branch * input spec init * cleans up spec * formatting * updates component name to text input * updates component name in spec * reverts dead file * adds text unit tests * formats file * fix lint warnings --------- Co-authored-by: Miroslav Stastny --- packages/web-components/src/text/text.spec.ts | 189 ++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 packages/web-components/src/text/text.spec.ts diff --git a/packages/web-components/src/text/text.spec.ts b/packages/web-components/src/text/text.spec.ts new file mode 100644 index 0000000000000..96dad554fd5a6 --- /dev/null +++ b/packages/web-components/src/text/text.spec.ts @@ -0,0 +1,189 @@ +import { expect, test } from '@playwright/test'; +import type { Locator, Page } from '@playwright/test'; +import { fixtureURL } from '../helpers.tests.js'; +import { Text } from './text.js'; +import { TextAlign, TextFont, TextSize, TextWeight } from './text.options.js'; + +test.describe('Text Component', () => { + let page: Page; + let element: Locator; + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + element = page.locator('fluent-text'); + await page.goto(fixtureURL('components-text--text')); + }); + + test.afterAll(async () => { + await page.close(); + }); + + const sizeAttributes = { + _100: '100', + _200: '200', + _300: '300', + _400: '400', + _500: '500', + _600: '600', + _700: '700', + _800: '800', + _900: '900', + _1000: '1000', + }; + + const weightAttributes = { + medium: 'medium', + regular: 'regular', + semibold: 'semibold', + bold: 'bold', + }; + + const alignAttributes = { + start: 'start', + end: 'end', + center: 'center', + justify: 'justify', + }; + + const fontAttributes = { + base: 'base', + numeric: 'numeric', + monospace: 'monospace', + }; + + test('should render without crashing', async () => { + await page.waitForSelector('fluent-text'); + await expect(element).toBeVisible(); + }); + + test(`should set and reflect and update the nowrap attribute and property on the internal control`, async () => { + await element.evaluate((node: Text) => { + node.nowrap = true; + }); + await expect(element).toHaveAttribute('nowrap', ''); + await expect(element).toHaveJSProperty('nowrap', true); + + await element.evaluate((node: Text) => { + node.nowrap = false; + }); + + await expect(element).not.toHaveAttribute('nowrap', ''); + await expect(element).toHaveJSProperty('nowrap', false); + }); + + test(`should set and reflect and update the truncate attribute and property on the internal control`, async () => { + await element.evaluate((node: Text) => { + node.truncate = true; + }); + await expect(element).toHaveAttribute('truncate', ''); + await expect(element).toHaveJSProperty('truncate', true); + + await element.evaluate((node: Text) => { + node.truncate = false; + }); + + await expect(element).not.toHaveAttribute('truncate', ''); + await expect(element).toHaveJSProperty('truncate', false); + }); + + test(`should set and reflect and update the italic attribute and property on the internal control`, async () => { + await element.evaluate((node: Text) => { + node.italic = true; + }); + await expect(element).toHaveAttribute('italic', ''); + await expect(element).toHaveJSProperty('italic', true); + + await element.evaluate((node: Text) => { + node.italic = false; + }); + + await expect(element).not.toHaveAttribute('italic', ''); + await expect(element).toHaveJSProperty('italic', false); + }); + + test(`should set and reflect and update the underline attribute and property on the internal control`, async () => { + await element.evaluate((node: Text) => { + node.underline = true; + }); + await expect(element).toHaveAttribute('underline', ''); + await expect(element).toHaveJSProperty('underline', true); + + await element.evaluate((node: Text) => { + node.underline = false; + }); + + await expect(element).not.toHaveAttribute('underline', ''); + await expect(element).toHaveJSProperty('underline', false); + }); + + test(`should set and reflect and update the strikethrough attribute and property on the internal control`, async () => { + await element.evaluate((node: Text) => { + node.strikethrough = true; + }); + await expect(element).toHaveAttribute('strikethrough', ''); + await expect(element).toHaveJSProperty('strikethrough', true); + + await element.evaluate((node: Text) => { + node.strikethrough = false; + }); + + await expect(element).not.toHaveAttribute('strikethrough', ''); + await expect(element).toHaveJSProperty('strikethrough', false); + }); + + test(`should set and reflect and update the block attribute and property on the internal control`, async () => { + await element.evaluate((node: Text) => { + node.block = true; + }); + await expect(element).toHaveAttribute('block', ''); + await expect(element).toHaveJSProperty('block', true); + + await element.evaluate((node: Text) => { + node.block = false; + }); + + await expect(element).not.toHaveAttribute('block', ''); + await expect(element).toHaveJSProperty('block', false); + }); + + for (const [, value] of Object.entries(sizeAttributes)) { + test(`should set and reflect the size attribute to \`${value}\` on the internal control`, async () => { + await element.evaluate((node: Text, sizeValue: string) => { + node.size = sizeValue as TextSize; + }, value as string); + + await expect(element).toHaveJSProperty('size', `${value}`); + await expect(element).toHaveAttribute('size', `${value}`); + }); + } + for (const [, value] of Object.entries(weightAttributes)) { + test(`should set and reflect the weight attribute to \`${value}\` on the internal control`, async () => { + await element.evaluate((node: Text, weightValue: string) => { + node.weight = weightValue as TextWeight; + }, value as string); + + await expect(element).toHaveJSProperty('weight', `${value}`); + await expect(element).toHaveAttribute('weight', `${value}`); + }); + } + for (const [, value] of Object.entries(alignAttributes)) { + test(`should set and reflect the align attribute to \`${value}\` on the internal control`, async () => { + await element.evaluate((node: Text, alignValue: string) => { + node.align = alignValue as TextAlign; + }, value as string); + + await expect(element).toHaveJSProperty('align', `${value}`); + await expect(element).toHaveAttribute('align', `${value}`); + }); + } + for (const [, value] of Object.entries(fontAttributes)) { + test(`should set and reflect the font attribute to \`${value}\` on the internal control`, async () => { + await element.evaluate((node: Text, fontValue: string) => { + node.font = fontValue as TextFont; + }, value as string); + + await expect(element).toHaveJSProperty('font', `${value}`); + await expect(element).toHaveAttribute('font', `${value}`); + }); + } +}); From b06d661dd28d9f6e332c1858590472525cf1e3fc Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Tue, 22 Aug 2023 13:07:02 -0700 Subject: [PATCH 145/203] add explicit exports for tokens and add package export for theme utils (#28952) --- ...-053d342f-924d-443d-a6e4-2f314b006450.json | 7 + packages/web-components/package.json | 4 + packages/web-components/src/theme/index.ts | 387 +++++++++++++++++- 3 files changed, 397 insertions(+), 1 deletion(-) create mode 100644 change/@fluentui-web-components-053d342f-924d-443d-a6e4-2f314b006450.json diff --git a/change/@fluentui-web-components-053d342f-924d-443d-a6e4-2f314b006450.json b/change/@fluentui-web-components-053d342f-924d-443d-a6e4-2f314b006450.json new file mode 100644 index 0000000000000..bbe3adcc8163b --- /dev/null +++ b/change/@fluentui-web-components-053d342f-924d-443d-a6e4-2f314b006450.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat(web-components): add explicit named exports for design tokens and package export path for theme utils", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 993622c819e45..26d3e9879dbba 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -130,6 +130,10 @@ "./toggle-button.js": { "types": "./dist/esm/toggle-button/define.d.ts", "default": "./dist/esm/toggle-button/define.js" + }, + "./theme.js": { + "types": "./dist/esm/theme/index.d.ts", + "default": "./dist/esm/theme/index.js" } }, "sideEffects": [ diff --git a/packages/web-components/src/theme/index.ts b/packages/web-components/src/theme/index.ts index f5f45a196e46b..5457adce5905a 100644 --- a/packages/web-components/src/theme/index.ts +++ b/packages/web-components/src/theme/index.ts @@ -1,2 +1,387 @@ -export * from './design-tokens.js'; +export { + borderRadiusNone, + borderRadiusSmall, + borderRadiusMedium, + borderRadiusLarge, + borderRadiusXLarge, + borderRadiusCircular, + fontSizeBase100, + fontSizeBase200, + fontSizeBase300, + fontSizeBase400, + fontSizeBase500, + fontSizeBase600, + fontSizeHero700, + fontSizeHero800, + fontSizeHero900, + fontSizeHero1000, + lineHeightBase100, + lineHeightBase200, + lineHeightBase300, + lineHeightBase400, + lineHeightBase500, + lineHeightBase600, + lineHeightHero700, + lineHeightHero800, + lineHeightHero900, + lineHeightHero1000, + fontFamilyBase, + fontFamilyMonospace, + fontFamilyNumeric, + fontWeightRegular, + fontWeightMedium, + fontWeightSemibold, + fontWeightBold, + strokeWidthThin, + strokeWidthThick, + strokeWidthThicker, + strokeWidthThickest, + spacingHorizontalNone, + spacingHorizontalXXS, + spacingHorizontalXS, + spacingHorizontalSNudge, + spacingHorizontalS, + spacingHorizontalMNudge, + spacingHorizontalM, + spacingHorizontalL, + spacingHorizontalXL, + spacingHorizontalXXL, + spacingHorizontalXXXL, + spacingVerticalNone, + spacingVerticalXXS, + spacingVerticalXS, + spacingVerticalSNudge, + spacingVerticalS, + spacingVerticalMNudge, + spacingVerticalM, + spacingVerticalL, + spacingVerticalXL, + spacingVerticalXXL, + spacingVerticalXXXL, + durationUltraFast, + durationFaster, + durationFast, + durationNormal, + durationSlow, + durationSlower, + durationUltraSlow, + curveAccelerateMax, + curveAccelerateMid, + curveAccelerateMin, + curveDecelerateMax, + curveDecelerateMid, + curveDecelerateMin, + curveEasyEaseMax, + curveEasyEase, + curveLinear, + colorNeutralForeground1, + colorNeutralForeground1Hover, + colorNeutralForeground1Pressed, + colorNeutralForeground1Selected, + colorNeutralForeground2, + colorNeutralForeground2Hover, + colorNeutralForeground2Pressed, + colorNeutralForeground2Selected, + colorNeutralForeground2BrandHover, + colorNeutralForeground2BrandPressed, + colorNeutralForeground2BrandSelected, + colorNeutralForeground3, + colorNeutralForeground3Hover, + colorNeutralForeground3Pressed, + colorNeutralForeground3Selected, + colorNeutralForeground3BrandHover, + colorNeutralForeground3BrandPressed, + colorNeutralForeground3BrandSelected, + colorNeutralForeground4, + colorNeutralForegroundDisabled, + colorNeutralForegroundInvertedDisabled, + colorBrandForegroundLink, + colorBrandForegroundLinkHover, + colorBrandForegroundLinkPressed, + colorBrandForegroundLinkSelected, + colorNeutralForeground2Link, + colorNeutralForeground2LinkHover, + colorNeutralForeground2LinkPressed, + colorNeutralForeground2LinkSelected, + colorCompoundBrandForeground1, + colorCompoundBrandForeground1Hover, + colorCompoundBrandForeground1Pressed, + colorBrandForeground1, + colorBrandForeground2, + colorNeutralForeground1Static, + colorNeutralForegroundStaticInverted, + colorNeutralForegroundInverted, + colorNeutralForegroundInvertedHover, + colorNeutralForegroundInvertedPressed, + colorNeutralForegroundInvertedSelected, + colorNeutralForegroundInverted2, + colorNeutralForegroundOnBrand, + colorNeutralForegroundInvertedLink, + colorNeutralForegroundInvertedLinkHover, + colorNeutralForegroundInvertedLinkPressed, + colorNeutralForegroundInvertedLinkSelected, + colorBrandForegroundInverted, + colorBrandForegroundInvertedHover, + colorBrandForegroundInvertedPressed, + colorBrandForegroundOnLight, + colorBrandForegroundOnLightHover, + colorBrandForegroundOnLightPressed, + colorBrandForegroundOnLightSelected, + colorNeutralBackground1, + colorNeutralBackground1Hover, + colorNeutralBackground1Pressed, + colorNeutralBackground1Selected, + colorNeutralBackground2, + colorNeutralBackground2Hover, + colorNeutralBackground2Pressed, + colorNeutralBackground2Selected, + colorNeutralBackground3, + colorNeutralBackground3Hover, + colorNeutralBackground3Pressed, + colorNeutralBackground3Selected, + colorNeutralBackground4, + colorNeutralBackground4Hover, + colorNeutralBackground4Pressed, + colorNeutralBackground4Selected, + colorNeutralBackground5, + colorNeutralBackground5Hover, + colorNeutralBackground5Pressed, + colorNeutralBackground5Selected, + colorNeutralBackground6, + colorNeutralBackgroundInverted, + colorNeutralBackgroundStatic, + colorSubtleBackground, + colorSubtleBackgroundHover, + colorSubtleBackgroundPressed, + colorSubtleBackgroundSelected, + colorSubtleBackgroundLightAlphaHover, + colorSubtleBackgroundLightAlphaPressed, + colorSubtleBackgroundLightAlphaSelected, + colorSubtleBackgroundInverted, + colorSubtleBackgroundInvertedHover, + colorSubtleBackgroundInvertedPressed, + colorSubtleBackgroundInvertedSelected, + colorTransparentBackground, + colorTransparentBackgroundHover, + colorTransparentBackgroundPressed, + colorTransparentBackgroundSelected, + colorNeutralBackgroundDisabled, + colorNeutralBackgroundInvertedDisabled, + colorNeutralStencil1, + colorNeutralStencil2, + colorNeutralStencil1Alpha, + colorNeutralStencil2Alpha, + colorBackgroundOverlay, + colorScrollbarOverlay, + colorBrandBackground, + colorBrandBackgroundHover, + colorBrandBackgroundPressed, + colorBrandBackgroundSelected, + colorCompoundBrandBackground, + colorCompoundBrandBackgroundHover, + colorCompoundBrandBackgroundPressed, + colorBrandBackgroundStatic, + colorBrandBackground2, + colorBrandBackgroundInverted, + colorBrandBackgroundInvertedHover, + colorBrandBackgroundInvertedPressed, + colorBrandBackgroundInvertedSelected, + colorNeutralStrokeAccessible, + colorNeutralStrokeAccessibleHover, + colorNeutralStrokeAccessiblePressed, + colorNeutralStrokeAccessibleSelected, + colorNeutralStroke1, + colorNeutralStroke1Hover, + colorNeutralStroke1Pressed, + colorNeutralStroke1Selected, + colorNeutralStroke2, + colorNeutralStroke3, + colorNeutralStrokeOnBrand, + colorNeutralStrokeOnBrand2, + colorNeutralStrokeOnBrand2Hover, + colorNeutralStrokeOnBrand2Pressed, + colorNeutralStrokeOnBrand2Selected, + colorBrandStroke1, + colorBrandStroke2, + colorCompoundBrandStroke, + colorCompoundBrandStrokeHover, + colorCompoundBrandStrokePressed, + colorNeutralStrokeDisabled, + colorNeutralStrokeInvertedDisabled, + colorTransparentStroke, + colorTransparentStrokeInteractive, + colorTransparentStrokeDisabled, + colorStrokeFocus1, + colorStrokeFocus2, + colorNeutralShadowAmbient, + colorNeutralShadowKey, + colorNeutralShadowAmbientLighter, + colorNeutralShadowKeyLighter, + colorNeutralShadowAmbientDarker, + colorNeutralShadowKeyDarker, + colorBrandShadowAmbient, + colorBrandShadowKey, + colorPaletteRedBackground1, + colorPaletteRedBackground2, + colorPaletteRedBackground3, + colorPaletteRedForeground1, + colorPaletteRedForeground2, + colorPaletteRedForeground3, + colorPaletteRedBorderActive, + colorPaletteRedBorder1, + colorPaletteRedBorder2, + colorPaletteGreenBackground1, + colorPaletteGreenBackground2, + colorPaletteGreenBackground3, + colorPaletteGreenForeground1, + colorPaletteGreenForeground2, + colorPaletteGreenForeground3, + colorPaletteGreenBorderActive, + colorPaletteGreenBorder1, + colorPaletteGreenBorder2, + colorPaletteDarkOrangeBackground1, + colorPaletteDarkOrangeBackground2, + colorPaletteDarkOrangeBackground3, + colorPaletteDarkOrangeForeground1, + colorPaletteDarkOrangeForeground2, + colorPaletteDarkOrangeForeground3, + colorPaletteDarkOrangeBorderActive, + colorPaletteDarkOrangeBorder1, + colorPaletteDarkOrangeBorder2, + colorPaletteYellowBackground1, + colorPaletteYellowBackground2, + colorPaletteYellowBackground3, + colorPaletteYellowForeground1, + colorPaletteYellowForeground2, + colorPaletteYellowForeground3, + colorPaletteYellowBorderActive, + colorPaletteYellowBorder1, + colorPaletteYellowBorder2, + colorPaletteBerryBackground1, + colorPaletteBerryBackground2, + colorPaletteBerryBackground3, + colorPaletteBerryForeground1, + colorPaletteBerryForeground2, + colorPaletteBerryForeground3, + colorPaletteBerryBorderActive, + colorPaletteBerryBorder1, + colorPaletteBerryBorder2, + colorPaletteLightGreenBackground1, + colorPaletteLightGreenBackground2, + colorPaletteLightGreenBackground3, + colorPaletteLightGreenForeground1, + colorPaletteLightGreenForeground2, + colorPaletteLightGreenForeground3, + colorPaletteLightGreenBorderActive, + colorPaletteLightGreenBorder1, + colorPaletteLightGreenBorder2, + colorPaletteMarigoldBackground1, + colorPaletteMarigoldBackground2, + colorPaletteMarigoldBackground3, + colorPaletteMarigoldForeground1, + colorPaletteMarigoldForeground2, + colorPaletteMarigoldForeground3, + colorPaletteMarigoldBorderActive, + colorPaletteMarigoldBorder1, + colorPaletteMarigoldBorder2, + colorPaletteDarkRedBackground2, + colorPaletteDarkRedForeground2, + colorPaletteDarkRedBorderActive, + colorPaletteCranberryBackground2, + colorPaletteCranberryForeground2, + colorPaletteCranberryBorderActive, + colorPalettePumpkinBackground2, + colorPalettePumpkinForeground2, + colorPalettePumpkinBorderActive, + colorPalettePeachBackground2, + colorPalettePeachForeground2, + colorPalettePeachBorderActive, + colorPaletteGoldBackground2, + colorPaletteGoldForeground2, + colorPaletteGoldBorderActive, + colorPaletteBrassBackground2, + colorPaletteBrassForeground2, + colorPaletteBrassBorderActive, + colorPaletteBrownBackground2, + colorPaletteBrownForeground2, + colorPaletteBrownBorderActive, + colorPaletteForestBackground2, + colorPaletteForestForeground2, + colorPaletteForestBorderActive, + colorPaletteSeafoamBackground2, + colorPaletteSeafoamForeground2, + colorPaletteSeafoamBorderActive, + colorPaletteDarkGreenBackground2, + colorPaletteDarkGreenForeground2, + colorPaletteDarkGreenBorderActive, + colorPaletteLightTealBackground2, + colorPaletteLightTealForeground2, + colorPaletteLightTealBorderActive, + colorPaletteTealBackground2, + colorPaletteTealForeground2, + colorPaletteTealBorderActive, + colorPaletteSteelBackground2, + colorPaletteSteelForeground2, + colorPaletteSteelBorderActive, + colorPaletteBlueBackground2, + colorPaletteBlueForeground2, + colorPaletteBlueBorderActive, + colorPaletteRoyalBlueBackground2, + colorPaletteRoyalBlueForeground2, + colorPaletteRoyalBlueBorderActive, + colorPaletteCornflowerBackground2, + colorPaletteCornflowerForeground2, + colorPaletteCornflowerBorderActive, + colorPaletteNavyBackground2, + colorPaletteNavyForeground2, + colorPaletteNavyBorderActive, + colorPaletteLavenderBackground2, + colorPaletteLavenderForeground2, + colorPaletteLavenderBorderActive, + colorPalettePurpleBackground2, + colorPalettePurpleForeground2, + colorPalettePurpleBorderActive, + colorPaletteGrapeBackground2, + colorPaletteGrapeForeground2, + colorPaletteGrapeBorderActive, + colorPaletteLilacBackground2, + colorPaletteLilacForeground2, + colorPaletteLilacBorderActive, + colorPalettePinkBackground2, + colorPalettePinkForeground2, + colorPalettePinkBorderActive, + colorPaletteMagentaBackground2, + colorPaletteMagentaForeground2, + colorPaletteMagentaBorderActive, + colorPalettePlumBackground2, + colorPalettePlumForeground2, + colorPalettePlumBorderActive, + colorPaletteBeigeBackground2, + colorPaletteBeigeForeground2, + colorPaletteBeigeBorderActive, + colorPaletteMinkBackground2, + colorPaletteMinkForeground2, + colorPaletteMinkBorderActive, + colorPalettePlatinumBackground2, + colorPalettePlatinumForeground2, + colorPalettePlatinumBorderActive, + colorPaletteAnchorBackground2, + colorPaletteAnchorForeground2, + colorPaletteAnchorBorderActive, + colorPaletteRedForegroundInverted, + colorPaletteGreenForegroundInverted, + colorPaletteYellowForegroundInverted, + shadow2, + shadow4, + shadow8, + shadow16, + shadow28, + shadow64, + shadow2Brand, + shadow4Brand, + shadow8Brand, + shadow16Brand, + shadow28Brand, + shadow64Brand, +} from './design-tokens.js'; export { setTheme, setThemeFor } from './set-theme.js'; From 482d7e831fbff11a4aaba6724f61acb42ead4202 Mon Sep 17 00:00:00 2001 From: Hale Rankin Date: Tue, 22 Aug 2023 21:00:47 -0700 Subject: [PATCH 146/203] Adds Tests For Fluent Divider Web Component (#28812) * Adds Divider playwright test. * Updates test. * Removes unused import. * Updates Divider tests, fixing failed test. --- .../src/divider/divider.spec.ts | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 packages/web-components/src/divider/divider.spec.ts diff --git a/packages/web-components/src/divider/divider.spec.ts b/packages/web-components/src/divider/divider.spec.ts new file mode 100644 index 0000000000000..324e83a26526a --- /dev/null +++ b/packages/web-components/src/divider/divider.spec.ts @@ -0,0 +1,138 @@ +import { expect, test } from '@playwright/test'; +import type { Locator, Page } from '@playwright/test'; +import { fixtureURL } from '../helpers.tests.js'; +import { Divider } from './divider.js'; + +test.describe('Divider', () => { + let page: Page; + let element: Locator; + let root: Locator; + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + + await page.goto(fixtureURL('components-divider--divider')); + + element = page.locator('fluent-divider'); + + root = page.locator('#root'); + }); + + test.afterAll(async () => { + await page.close(); + }); + + test('should set a default `role` attribute of "separator"', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(element).toHaveAttribute('role', 'separator'); + }); + + test('should set the `role` attribute equal to the role provided', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(element).toHaveAttribute('role', 'presentation'); + + await element.evaluate((node: Divider) => { + node.role = 'separator'; + }); + + await expect(element).toHaveAttribute('role', 'separator'); + }); + + test('should set the `aria-orientation` attribute equal to the `orientation` value', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(element).toHaveAttribute('aria-orientation', 'vertical'); + + await element.evaluate((node: Divider) => { + node.orientation = 'horizontal'; + }); + + await expect(element).toHaveAttribute('aria-orientation', 'horizontal'); + }); + + test('should NOT set the `aria-orientation` property equal to `orientation` value if the `role` is presentational', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(element).toHaveAttribute('aria-orientation', 'vertical'); + + await element.evaluate((node: Divider) => { + node.role = 'presentation'; + }); + + await expect(element).not.toHaveJSProperty('aria-orientation', 'vertical'); + await expect(element).not.toHaveJSProperty('aria-orientation', 'horizontal'); + }); + + test('should initialize to the provided value attribute if set post-connection', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await element.evaluate((node: Divider) => { + node.alignContent = 'start'; + }); + + await expect(element).toHaveJSProperty('alignContent', 'start'); + + await element.evaluate((node: Divider) => { + node.alignContent = 'center'; + }); + + await expect(element).toHaveJSProperty('alignContent', 'center'); + + await element.evaluate((node: Divider) => { + node.alignContent = 'end'; + }); + + await expect(element).toHaveJSProperty('alignContent', 'end'); + + await element.evaluate((node: Divider) => { + node.appearance = 'default'; + }); + + await expect(element).toHaveJSProperty('appearance', 'default'); + + await element.evaluate((node: Divider) => { + node.appearance = 'strong'; + }); + + await expect(element).toHaveJSProperty('appearance', 'strong'); + + await element.evaluate((node: Divider) => { + node.appearance = 'brand'; + }); + + await expect(element).toHaveJSProperty('appearance', 'brand'); + await element.evaluate((node: Divider) => { + node.appearance = 'subtle'; + }); + + await expect(element).toHaveJSProperty('appearance', 'subtle'); + + await element.evaluate((node: Divider) => { + node.inset = true; + }); + + await expect(element).toHaveJSProperty('inset', true); + }); +}); From 9cca62197bbe085789a3ae681a49b84711013bcc Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Tue, 22 Aug 2023 21:04:08 -0700 Subject: [PATCH 147/203] Label unit tests (#28830) * radio init * styles radio * reverts branch * input spec init * cleans up spec * formatting * updates component name to text input * updates component name in spec * reverts dead file * label unit tests --- .../web-components/src/label/label.spec.ts | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 packages/web-components/src/label/label.spec.ts diff --git a/packages/web-components/src/label/label.spec.ts b/packages/web-components/src/label/label.spec.ts new file mode 100644 index 0000000000000..7aa08fe5a8f18 --- /dev/null +++ b/packages/web-components/src/label/label.spec.ts @@ -0,0 +1,143 @@ +import { expect, test } from '@playwright/test'; +import type { Locator, Page } from '@playwright/test'; +import { fixtureURL } from '../helpers.tests.js'; +import type { Label } from './label.js'; + +test.describe('Label', () => { + let page: Page; + let element: Locator; + let root: Locator; + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + + element = page.locator('fluent-label'); + root = page.locator('#root'); + + await page.goto(fixtureURL('components-label--label')); + }); + + test.afterAll(async () => { + await page.close(); + }); + + test('should set default attribute values', async () => { + await expect(element).toHaveAttribute('size', 'medium'); + await expect(element).toHaveJSProperty('size', 'medium'); + + await expect(element).toHaveAttribute('weight', 'regular'); + await expect(element).toHaveJSProperty('weight', 'regular'); + }); + + test('should reflect size attribute', async () => { + await element.evaluate((node: Label) => { + node.size = 'small'; + }); + + await expect(element).toHaveAttribute('size', 'small'); + await expect(element).toHaveJSProperty('size', 'small'); + + await element.evaluate((node: Label) => { + node.size = 'medium'; + }); + + await expect(element).toHaveAttribute('size', 'medium'); + await expect(element).toHaveJSProperty('size', 'medium'); + + await element.evaluate((node: Label) => { + node.size = 'large'; + }); + await expect(element).toHaveAttribute('size', 'large'); + await expect(element).toHaveJSProperty('size', 'large'); + }); + + test('should reflect weight attribute', async () => { + await element.evaluate((node: Label) => { + node.weight = 'regular'; + }); + await expect(element).toHaveAttribute('weight', 'regular'); + await expect(element).toHaveJSProperty('weight', 'regular'); + + await element.evaluate((node: Label) => { + node.weight = 'semibold'; + }); + await expect(element).toHaveAttribute('weight', 'semibold'); + await expect(element).toHaveJSProperty('weight', 'semibold'); + }); + + test('should reflect disabled attribute', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + Label + `; + }); + + await expect(element).toHaveAttribute('disabled', ''); + await expect(element).toHaveJSProperty('disabled', true); + }); + + test('should reflect required attribute and show asterisk', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + Label + `; + }); + + const asterisk = element.locator('span.asterisk'); + + await expect(element).toHaveAttribute('required', ''); + await expect(element).toHaveJSProperty('required', true); + await expect(asterisk).toBeVisible(); + }); + + test('should hide asterisk when required attribute is not set', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + Label + `; + }); + + const asterisk = element.locator('span.asterisk'); + await expect(element).not.toHaveAttribute('required', ''); + await expect(element).toHaveJSProperty('required', false); + await expect(asterisk).toBeHidden(); + }); + + test('should reflect changes in size, weight, disabled, and required attributes', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + Label + `; + }); + await expect(element).toHaveAttribute('size', 'medium'); + await expect(element).toHaveJSProperty('size', 'medium'); + + await expect(element).toHaveAttribute('weight', 'regular'); + await expect(element).toHaveJSProperty('weight', 'regular'); + + await expect(element).not.toHaveAttribute('disabled', ''); + await expect(element).toHaveJSProperty('disabled', false); + + await expect(element).not.toHaveAttribute('required', ''); + await expect(element).toHaveJSProperty('required', false); + + await element.evaluate((node: Label) => { + node.size = 'large'; + node.weight = 'semibold'; + node.disabled = true; + node.required = true; + }); + + await expect(element).toHaveAttribute('size', 'large'); + await expect(element).toHaveJSProperty('size', 'large'); + + await expect(element).toHaveAttribute('weight', 'semibold'); + await expect(element).toHaveJSProperty('weight', 'semibold'); + + await expect(element).toHaveAttribute('disabled', ''); + await expect(element).toHaveJSProperty('disabled', true); + + await expect(element).toHaveAttribute('required', ''); + await expect(element).toHaveJSProperty('required', true); + }); +}); From 8fd7a0678d8c2bc64cc9fcc072c21d2e8463da83 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Wed, 23 Aug 2023 04:18:06 +0000 Subject: [PATCH 148/203] applying package updates --- apps/vr-tests-web-components/package.json | 2 +- ...ents-053d342f-924d-443d-a6e4-2f314b006450.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 5 files changed, 27 insertions(+), 10 deletions(-) delete mode 100644 change/@fluentui-web-components-053d342f-924d-443d-a6e4-2f314b006450.json diff --git a/apps/vr-tests-web-components/package.json b/apps/vr-tests-web-components/package.json index b4e18a5a3192a..45b562856bb2e 100644 --- a/apps/vr-tests-web-components/package.json +++ b/apps/vr-tests-web-components/package.json @@ -23,7 +23,7 @@ "dependencies": { "@fluentui/react-button": "^9.2.3", "@fluentui/react-storybook-addon": "*", - "@fluentui/web-components": "3.0.0-alpha.30", + "@fluentui/web-components": "3.0.0-alpha.31", "tslib": "^2.1.0" } } diff --git a/change/@fluentui-web-components-053d342f-924d-443d-a6e4-2f314b006450.json b/change/@fluentui-web-components-053d342f-924d-443d-a6e4-2f314b006450.json deleted file mode 100644 index bbe3adcc8163b..0000000000000 --- a/change/@fluentui-web-components-053d342f-924d-443d-a6e4-2f314b006450.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat(web-components): add explicit named exports for design tokens and package export path for theme utils", - "packageName": "@fluentui/web-components", - "email": "chhol@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 9ccbf619586aa..de334a06c8bb6 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Wed, 23 Aug 2023 04:18:01 GMT", + "tag": "@fluentui/web-components_v3.0.0-alpha.31", + "version": "3.0.0-alpha.31", + "comments": { + "prerelease": [ + { + "author": "chhol@microsoft.com", + "package": "@fluentui/web-components", + "commit": "913d17528272d230a1c6f72652271faaebeb1a12", + "comment": "feat(web-components): add explicit named exports for design tokens and package export path for theme utils" + } + ] + } + }, { "date": "Tue, 22 Aug 2023 04:17:13 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.30", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index 76dd281d909bf..cd7baad3fde8a 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Tue, 22 Aug 2023 04:17:13 GMT and should not be manually modified. +This log was last generated on Wed, 23 Aug 2023 04:18:01 GMT and should not be manually modified. +## [3.0.0-alpha.31](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.31) + +Wed, 23 Aug 2023 04:18:01 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.30..@fluentui/web-components_v3.0.0-alpha.31) + +### Changes + +- feat(web-components): add explicit named exports for design tokens and package export path for theme utils ([PR #28952](https://github.com/microsoft/fluentui/pull/28952) by chhol@microsoft.com) + ## [3.0.0-alpha.30](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.30) Tue, 22 Aug 2023 04:17:13 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 26d3e9879dbba..8da56e64289b0 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -1,7 +1,7 @@ { "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", - "version": "3.0.0-alpha.30", + "version": "3.0.0-alpha.31", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 777c05e63bce2e0d4bdf731855b17f04e6ec0a1d Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Tue, 22 Aug 2023 21:26:37 -0700 Subject: [PATCH 149/203] menu list unit tests (#28857) * radio init * styles radio * reverts branch * input spec init * cleans up spec * formatting * updates component name to text input * updates component name in spec * reverts dead file * adds menulist unit tests * menu-list tests: updates test names, fixes role attribute in radio test --- .../src/menu-list/menu-list.spec.ts | 547 ++++++++++++++++++ 1 file changed, 547 insertions(+) create mode 100644 packages/web-components/src/menu-list/menu-list.spec.ts diff --git a/packages/web-components/src/menu-list/menu-list.spec.ts b/packages/web-components/src/menu-list/menu-list.spec.ts new file mode 100644 index 0000000000000..af668456fa0ad --- /dev/null +++ b/packages/web-components/src/menu-list/menu-list.spec.ts @@ -0,0 +1,547 @@ +import { expect, test } from '@playwright/test'; +import type { Locator, Page } from '@playwright/test'; +import { fixtureURL } from '../helpers.tests.js'; +import type { MenuList } from './menu-list.js'; + +test.describe('Menu', () => { + let page: Page; + let element: Locator; + let root: Locator; + let menuItems: Locator; + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + + element = page.locator('fluent-menu-list'); + + root = page.locator('#root'); + + menuItems = element.locator('fluent-menu-item'); + + await page.goto(fixtureURL('components-menulist--menu-list')); + }); + + test.afterAll(async () => { + await page.close(); + }); + + test('should have a role of `menu`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Menu item + + `; + }); + + await expect(element).toHaveAttribute('role', 'menu'); + }); + + test('should set `tabindex` of the first focusable menu item to 0', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Menu item + Menu item + + `; + }); + + await expect(menuItems.first()).toHaveAttribute('tabindex', '0'); + }); + + test('should NOT set any `tabindex` on non-menu-item elements', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Menu item +
Not a menu item
+
+ `; + }); + + const divider = element.locator('div'); + + expect(await divider.getAttribute('tabindex')).toBeNull(); + }); + + test('should focus on first menu item when focus is called', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Menu item + Menu item + + `; + }); + + await element.waitFor({ state: 'attached' }); + + await expect(menuItems.first()).toHaveAttribute('tabindex', '0'); + + await root.evaluate(node => { + document.querySelector('fluent-menu-list')?.focus(); + }); + + expect( + await menuItems.first().evaluate(node => { + return node.isSameNode(document.activeElement); + }), + ).toBeTruthy(); + }); + + test('should not throw when focus is called with no items', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await root.evaluate(node => { + document.querySelector('fluent-menu-list')?.focus(); + }); + + expect(await page.evaluate(() => document.activeElement?.id)).toBe(''); + }); + + test('should not throw when focus is called before initialization is complete', async () => { + await root.evaluate(node => { + node.innerHTML = ''; + + const menu = document.createElement('fluent-menu-list'); + + menu.focus(); + + node.append(menu); + }); + + expect(await page.evaluate(() => document.activeElement?.id)).toBe(''); + }); + + test('should focus disabled items', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Menu item + Menu item + + `; + }); + + const firstMenuItem = menuItems.first(); + + await expect(firstMenuItem).toBeDisabled(); + + await expect(firstMenuItem).toHaveAttribute('tabindex', '0'); + + await firstMenuItem.focus(); + + await expect(firstMenuItem).toBeFocused(); + }); + + ['menuitem', 'menuitemcheckbox', 'menuitemradio'].forEach(role => { + test(`should accept elements as focusable child with "${role}" role`, async () => { + await root.evaluate( + (node, { role }) => { + node.innerHTML = /* html */ ` + +
Menu item
+
+ `; + }, + { role }, + ); + + await expect(page.locator(`fluent-menu-list [role="${role}"]`).first()).toHaveAttribute('tabindex', '0'); + }); + }); + + test('should not navigate to hidden items when changed after connection', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Menu item 1 + Menu item 2 + Menu item 3 + Menu item 4 + + `; + }); + + await expect.soft(menuItems).toHaveCount(4); + + await menuItems.nth(2).evaluate(node => node.toggleAttribute('hidden')); + + await element.evaluate(node => { + node.focus(); + }); + + await (await element.elementHandle())?.waitForElementState('stable'); + + await expect(menuItems.nth(0)).toBeFocused(); + + await element.press('ArrowDown'); + + await expect(menuItems.nth(1)).toBeFocused(); + + await element.press('ArrowDown'); + + await expect(menuItems.nth(2)).not.toBeFocused(); + + await expect(menuItems.nth(3)).toBeFocused(); + + await element.press('ArrowUp'); + + await expect(menuItems.nth(2)).not.toBeFocused(); + + await expect(menuItems.nth(1)).toBeFocused(); + + await element.press('ArrowUp'); + + await expect(menuItems.nth(0)).toBeFocused(); + + await menuItems.nth(2).evaluate(node => { + node.removeAttribute('hidden'); + }); + + await (await element.elementHandle())?.waitForElementState('stable'); + + await element.press('ArrowDown'); + + await expect(menuItems.nth(1)).toBeFocused(); + + await element.press('ArrowDown'); + + await expect(menuItems.nth(2)).toBeFocused(); + }); + + test('should treat all checkbox menu items as individually selectable items', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Menu item 1 + Menu item 2 + Menu item 3 + Menu item 4 + + `; + }); + + const menuItemsCount = await menuItems.count(); + + for (let i = 0; i < menuItemsCount; i++) { + const item = menuItems.nth(i); + + await expect(item).toHaveAttribute('aria-checked', 'false'); + + await item.click(); + + await expect(item).toHaveAttribute('aria-checked', 'true'); + + await item.click(); + + await expect(item).toHaveAttribute('aria-checked', 'false'); + } + }); + + test(`should treat all radio menu items as a radiogroup and limit selection to one item within the group`, async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Menu item 1 + Menu item 2 + Menu item 3 + + `; + }); + + await menuItems.first().click(); + + await expect(menuItems.first()).toHaveAttribute('aria-checked', 'true'); + + await expect(menuItems.nth(1)).toHaveAttribute('aria-checked', 'false'); + + await expect(menuItems.nth(2)).toHaveAttribute('aria-checked', 'false'); + + await menuItems.nth(1).click(); + + await expect(menuItems.first()).toHaveAttribute('aria-checked', 'false'); + + await expect(menuItems.nth(1)).toHaveAttribute('aria-checked', 'true'); + + await expect(menuItems.nth(2)).toHaveAttribute('aria-checked', 'false'); + + await menuItems.nth(2).click(); + + await expect(menuItems.first()).toHaveAttribute('aria-checked', 'false'); + + await expect(menuItems.nth(1)).toHaveAttribute('aria-checked', 'false'); + + await expect(menuItems.nth(2)).toHaveAttribute('aria-checked', 'true'); + }); + + test('should use elements with `[role="separator"]` to divide radio menu items into different radio groups', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Menu item 1 + Menu item 2 + + Menu item 3 + Menu item 4 + + `; + }); + + await menuItems.nth(0).click(); + + await expect(menuItems.nth(0)).toHaveAttribute('aria-checked', 'true'); + await expect(menuItems.nth(1)).toHaveAttribute('aria-checked', 'false'); + await expect(menuItems.nth(2)).toHaveAttribute('aria-checked', 'false'); + await expect(menuItems.nth(3)).toHaveAttribute('aria-checked', 'false'); + + await menuItems.nth(1).click(); + + await expect(menuItems.nth(0)).toHaveAttribute('aria-checked', 'false'); + await expect(menuItems.nth(1)).toHaveAttribute('aria-checked', 'true'); + await expect(menuItems.nth(2)).toHaveAttribute('aria-checked', 'false'); + await expect(menuItems.nth(3)).toHaveAttribute('aria-checked', 'false'); + + await menuItems.nth(2).click(); + + await expect(menuItems.nth(0)).toHaveAttribute('aria-checked', 'false'); + await expect(menuItems.nth(1)).toHaveAttribute('aria-checked', 'true'); + await expect(menuItems.nth(2)).toHaveAttribute('aria-checked', 'true'); + await expect(menuItems.nth(3)).toHaveAttribute('aria-checked', 'false'); + + await menuItems.nth(3).click(); + + await expect(menuItems.nth(0)).toHaveAttribute('aria-checked', 'false'); + await expect(menuItems.nth(1)).toHaveAttribute('aria-checked', 'true'); + await expect(menuItems.nth(2)).toHaveAttribute('aria-checked', 'false'); + await expect(menuItems.nth(3)).toHaveAttribute('aria-checked', 'true'); + }); + + test('should navigate the menu on arrow up/down keys', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Menu item 1 + Menu item 2 + Menu item 3 + Menu item 4 + + `; + }); + + await element.waitFor({ state: 'attached' }); + + await element.evaluate(node => { + node.focus(); + }); + + await expect(menuItems).toHaveCount(4); + + await expect(menuItems.first()).toBeFocused(); + + await element.press('ArrowDown'); + + await expect(menuItems.nth(1)).toBeFocused(); + + await element.press('ArrowDown'); + + await expect(menuItems.nth(2)).toBeFocused(); + + await element.press('ArrowDown'); + + await expect(menuItems.nth(3)).toBeFocused(); + }); + + test('should navigate to submenu, close it with escape key, and return focus to the first menu item', async () => { + test.slow(); + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Menu item 1 + + Menu item 1.1 + Menu item 1.2 + Menu item 1.3 + + + + `; + }); + + await element.first().evaluate(node => { + node.focus(); + }); + + await element.first().press('ArrowRight'); + + await (await element.first().elementHandle())?.waitForElementState('stable'); + + await expect(menuItems.nth(1)).toBeFocused(); + + await element.first().press('Escape'); + + await (await element.first().elementHandle())?.waitForElementState('stable'); + + await expect(menuItems.first()).toBeFocused(); + }); + + test('should not navigate to hidden items when set before connection', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Menu item 1 + + Menu item 3 + Menu item 4 + + `; + + // reset the focus to the window to help with flakiness + window.focus(); + }); + + await (await element.elementHandle())?.waitForElementState('stable'); + + await element.evaluate(node => { + node.focus(); + }); + + await expect(menuItems.nth(0)).toBeFocused({ timeout: 500 }); + + await element.evaluate(node => { + node.dispatchEvent( + new KeyboardEvent('keydown', { + key: 'ArrowDown', + }), + ); + }); + + await expect(menuItems.nth(2)).toBeFocused(); + + await element.evaluate(node => { + node.dispatchEvent( + new KeyboardEvent('keydown', { + key: 'ArrowDown', + }), + ); + }); + + await expect(menuItems.nth(3)).toBeFocused(); + + await element.evaluate(node => { + node.dispatchEvent( + new KeyboardEvent('keydown', { + key: 'ArrowUp', + }), + ); + }); + + await expect(menuItems.nth(2)).toBeFocused(); + + await element.evaluate(node => { + node.dispatchEvent( + new KeyboardEvent('keydown', { + key: 'ArrowUp', + }), + ); + }); + + await expect(menuItems.nth(0)).toBeFocused(); + }); + + test('should set the data-indent attribute to 0 correctly on all MenuItem elements when role of menuitem and not content in start slot', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Menu Item 1 + Menu item 2 + Menu item 3 + Menu item 4 + + `; + }); + await expect(menuItems.nth(0)).toHaveAttribute('data-indent', '0'); + await expect(menuItems.nth(1)).toHaveAttribute('data-indent', '0'); + await expect(menuItems.nth(2)).toHaveAttribute('data-indent', '0'); + await expect(menuItems.nth(3)).toHaveAttribute('data-indent', '0'); + }); + + test('should set the data-indent attribute to 1 correctly on all MenuItem elements when a menuitem in the menu as a role of menuitemcheckbox', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + + Menu item 2 + Menu item 3 + Menu item 4 + + `; + }); + await expect(menuItems.nth(0)).toHaveAttribute('data-indent', '1'); + await expect(menuItems.nth(1)).toHaveAttribute('data-indent', '1'); + await expect(menuItems.nth(2)).toHaveAttribute('data-indent', '1'); + await expect(menuItems.nth(3)).toHaveAttribute('data-indent', '1'); + }); + + test('should set the data-indent attribute to 1 correctly on all MenuItem elements when a menuitem in the menu as a role of menuitemradio', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + + Menu item 2 + Menu item 3 + Menu item 4 + + `; + }); + await expect(menuItems.nth(0)).toHaveAttribute('data-indent', '1'); + await expect(menuItems.nth(1)).toHaveAttribute('data-indent', '1'); + await expect(menuItems.nth(2)).toHaveAttribute('data-indent', '1'); + await expect(menuItems.nth(3)).toHaveAttribute('data-indent', '1'); + }); + + test('should set the data-indent attribute to 2 correctly on all MenuItem elements when a menuitem in the menu has a role of menuitemcheckbox and content in the start slot', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + + Item 1 + Icon + + Menu item 2 + Menu item 3 + Menu item 4 + + `; + }); + await expect(menuItems.nth(0)).toHaveAttribute('data-indent', '2'); + await expect(menuItems.nth(1)).toHaveAttribute('data-indent', '2'); + await expect(menuItems.nth(2)).toHaveAttribute('data-indent', '2'); + await expect(menuItems.nth(3)).toHaveAttribute('data-indent', '2'); + }); + + test('should set the data-indent attribute to 2 correctly on all MenuItem elements when a menuitem in the menu has a role of menuitemradio and content in the start slot', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + + Item 1 + Icon + + Menu item 2 + Menu item 3 + Menu item 4 + + `; + }); + await expect(menuItems.nth(0)).toHaveAttribute('data-indent', '2'); + await expect(menuItems.nth(1)).toHaveAttribute('data-indent', '2'); + await expect(menuItems.nth(2)).toHaveAttribute('data-indent', '2'); + await expect(menuItems.nth(3)).toHaveAttribute('data-indent', '2'); + }); +}); From beec46c2e017153238777e1a26d90c4446d2eac9 Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Wed, 23 Aug 2023 13:26:13 -0700 Subject: [PATCH 150/203] badge unit testing (#28832) * adds badge unit tests * badge tests: removes duplicate test, adds color attribute expect state for 'warning' --- .../web-components/src/badge/badge.spec.ts | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 packages/web-components/src/badge/badge.spec.ts diff --git a/packages/web-components/src/badge/badge.spec.ts b/packages/web-components/src/badge/badge.spec.ts new file mode 100644 index 0000000000000..bb526516088e2 --- /dev/null +++ b/packages/web-components/src/badge/badge.spec.ts @@ -0,0 +1,178 @@ +import { expect, test } from '@playwright/test'; +import type { Locator, Page } from '@playwright/test'; +import { fixtureURL } from '../helpers.tests.js'; +import type { Badge } from './badge.js'; + +test.describe('Badge component', () => { + let page: Page; + let element: Locator; + let root: Locator; + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + + element = page.locator('fluent-badge'); + root = page.locator('#root'); + + await page.goto(fixtureURL('components-badge--badge')); + }); + + test.afterAll(async () => { + await page.close(); + }); + + test('should set default attribute values', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + await expect(element).toHaveAttribute('appearance', 'filled'); + await expect(element).toHaveJSProperty('appearance', 'filled'); + + await expect(element).toHaveAttribute('color', 'brand'); + await expect(element).toHaveJSProperty('color', 'brand'); + }); + + test('should reflect color attribute and update property', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + await expect(element).toHaveAttribute('color', 'brand'); + await expect(element).toHaveJSProperty('color', 'brand'); + + await element.evaluate((node: Badge) => { + node.color = 'danger'; + }); + await expect(element).toHaveAttribute('color', 'danger'); + await expect(element).toHaveJSProperty('color', 'danger'); + + await element.evaluate((node: Badge) => { + node.color = 'important'; + }); + await expect(element).toHaveAttribute('color', 'important'); + await expect(element).toHaveJSProperty('color', 'important'); + + await element.evaluate((node: Badge) => { + node.color = 'informative'; + }); + await expect(element).toHaveAttribute('color', 'informative'); + await expect(element).toHaveJSProperty('color', 'informative'); + + await element.evaluate((node: Badge) => { + node.color = 'severe'; + }); + await expect(element).toHaveAttribute('color', 'severe'); + await expect(element).toHaveJSProperty('color', 'severe'); + + await element.evaluate((node: Badge) => { + node.color = 'subtle'; + }); + await expect(element).toHaveAttribute('color', 'subtle'); + await expect(element).toHaveJSProperty('color', 'subtle'); + + await element.evaluate((node: Badge) => { + node.color = 'success'; + }); + await expect(element).toHaveAttribute('color', 'success'); + await expect(element).toHaveJSProperty('color', 'success'); + + await element.evaluate((node: Badge) => { + node.color = 'warning'; + }); + await expect(element).toHaveAttribute('color', 'warning'); + await expect(element).toHaveJSProperty('color', 'warning'); + }); + + test('should reflect size attribute and update property', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + await expect(element).toHaveAttribute('size', 'tiny'); + await expect(element).toHaveJSProperty('size', 'tiny'); + + await element.evaluate((node: Badge) => { + node.size = 'extra-small'; + }); + await expect(element).toHaveAttribute('size', 'extra-small'); + await expect(element).toHaveJSProperty('size', 'extra-small'); + + await element.evaluate((node: Badge) => { + node.size = 'small'; + }); + await expect(element).toHaveAttribute('size', 'small'); + await expect(element).toHaveJSProperty('size', 'small'); + + await element.evaluate((node: Badge) => { + node.size = 'medium'; + }); + await expect(element).toHaveAttribute('size', 'medium'); + await expect(element).toHaveJSProperty('size', 'medium'); + + await element.evaluate((node: Badge) => { + node.size = 'large'; + }); + await expect(element).toHaveAttribute('size', 'large'); + await expect(element).toHaveJSProperty('size', 'large'); + + await element.evaluate((node: Badge) => { + node.size = 'extra-large'; + }); + await expect(element).toHaveAttribute('size', 'extra-large'); + await expect(element).toHaveJSProperty('size', 'extra-large'); + }); + + test('should reflect appearance attribute and update property', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + await expect(element).toHaveAttribute('appearance', 'filled'); + await expect(element).toHaveJSProperty('appearance', 'filled'); + + await element.evaluate((node: Badge) => { + node.appearance = 'ghost'; + }); + await expect(element).toHaveAttribute('appearance', 'ghost'); + await expect(element).toHaveJSProperty('appearance', 'ghost'); + + await element.evaluate((node: Badge) => { + node.appearance = 'outline'; + }); + await expect(element).toHaveAttribute('appearance', 'outline'); + await expect(element).toHaveJSProperty('appearance', 'outline'); + + await element.evaluate((node: Badge) => { + node.appearance = 'tint'; + }); + await expect(element).toHaveAttribute('appearance', 'tint'); + await expect(element).toHaveJSProperty('appearance', 'tint'); + }); + + test('should reflect shape attribute and update property', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + await expect(element).toHaveAttribute('shape', 'circular'); + await expect(element).toHaveJSProperty('shape', 'circular'); + + await element.evaluate((node: Badge) => { + node.shape = 'rounded'; + }); + await expect(element).toHaveAttribute('shape', 'rounded'); + await expect(element).toHaveJSProperty('shape', 'rounded'); + + await element.evaluate((node: Badge) => { + node.shape = 'square'; + }); + await expect(element).toHaveAttribute('shape', 'square'); + await expect(element).toHaveJSProperty('shape', 'square'); + }); +}); From b753a5c9cb62ae1faf5a8cc94e0504005f4da9d2 Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Wed, 23 Aug 2023 13:34:38 -0700 Subject: [PATCH 151/203] adds text input unit tests (#28859) * adds text input unit tests * fixes fixtureURL * text input: updates valid tel value test * text input tests: updates size attr tests --- .../src/text-input/text-input.spec.ts | 644 ++++++++++++++++++ 1 file changed, 644 insertions(+) create mode 100644 packages/web-components/src/text-input/text-input.spec.ts diff --git a/packages/web-components/src/text-input/text-input.spec.ts b/packages/web-components/src/text-input/text-input.spec.ts new file mode 100644 index 0000000000000..ee1a25acc0709 --- /dev/null +++ b/packages/web-components/src/text-input/text-input.spec.ts @@ -0,0 +1,644 @@ +import { spinalCase } from '@microsoft/fast-web-utilities'; +import { expect, test } from '@playwright/test'; +import type { Locator, Page } from '@playwright/test'; +import { fixtureURL } from '../helpers.tests.js'; +import type { TextInput } from './text-input.js'; + +test.describe('TextInput', () => { + let page: Page; + let element: Locator; + let root: Locator; + let control: Locator; + let label: Locator; + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + + element = page.locator('fluent-text-input'); + + root = page.locator('#root'); + + control = element.locator('.control'); + + label = element.locator('.label'); + + await page.goto(fixtureURL('components-textinput--text-input')); + }); + + test.afterAll(async () => { + await page.close(); + }); + + test('should set the `autofocus` attribute on the internal control', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(control).toHaveAttribute('autofocus', ''); + }); + + test('should set the `disabled` attribute on the internal control', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(control).toHaveAttribute('disabled', ''); + }); + + test('should set the `readonly` attribute on the internal control', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(control).toHaveAttribute('readonly', ''); + }); + + test('should set the `required` attribute on the internal control', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(control).toHaveAttribute('required', ''); + }); + + test('should set the `spellcheck` attribute on the internal control', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(control).toHaveAttribute('spellcheck', ''); + }); + + test.describe('should set the attribute on the internal control', () => { + const attributes = { + maxlength: 14, + minlength: 14, + name: 'foo', + placeholder: 'foo', + size: 4, + list: 'listId', + ariaAtomic: 'true', + ariaBusy: 'false', + ariaControls: 'testId', + ariaCurrent: 'page', + ariaDescribedby: 'testId', + ariaDetails: 'testId', + ariaDisabled: 'true', + ariaErrormessage: 'test', + ariaFlowto: 'testId', + ariaHaspopup: 'true', + ariaHidden: 'true', + ariaInvalid: 'spelling', + ariaKeyshortcuts: 'F4', + ariaLabel: 'Foo label', + ariaLabelledby: 'testId', + ariaLive: 'polite', + ariaOwns: 'testId', + ariaRelevant: 'removals', + ariaRoledescription: 'search', + }; + + for (const [attribute, value] of Object.entries(attributes)) { + const attrToken = spinalCase(attribute); + + test(`should set the \`${attrToken}\` attribute on the internal control`, async () => { + await root.evaluate( + (node, { attrToken, value }) => { + node.innerHTML = /* html */ ` + + `; + }, + { attrToken, value }, + ); + + await expect(control).toHaveAttribute(attrToken, `${value}`); + }); + } + }); + test('should reflect control-size attribute values', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(element).toHaveAttribute('control-size', 'small'); + await expect(element).toHaveJSProperty('controlSize', 'small'); + + await element.evaluate((node: TextInput) => { + node.controlSize = 'medium'; + }); + + await expect(element).toHaveAttribute('control-size', 'medium'); + await expect(element).toHaveJSProperty('controlSize', 'medium'); + + await element.evaluate((node: TextInput) => { + node.controlSize = 'large'; + }); + await expect(element).toHaveAttribute('control-size', 'large'); + await expect(element).toHaveJSProperty('controlSize', 'large'); + + await element.evaluate((node: TextInput) => { + node.controlSize = 'small'; + }); + await expect(element).toHaveAttribute('control-size', 'small'); + await expect(element).toHaveJSProperty('controlSize', 'small'); + }); + + test('should reflect appearance attribute values', async () => { + await element.evaluate((node: TextInput) => { + node.appearance = 'outline'; + }); + + await expect(element).toHaveAttribute('appearance', 'outline'); + await expect(element).toHaveJSProperty('appearance', 'outline'); + + await element.evaluate((node: TextInput) => { + node.appearance = 'underline'; + }); + + await expect(element).toHaveAttribute('appearance', 'underline'); + await expect(element).toHaveJSProperty('appearance', 'underline'); + + await element.evaluate((node: TextInput) => { + node.appearance = 'filled-darker'; + }); + await expect(element).toHaveAttribute('appearance', 'filled-darker'); + await expect(element).toHaveJSProperty('appearance', 'filled-darker'); + + await element.evaluate((node: TextInput) => { + node.appearance = 'filled-lighter'; + }); + await expect(element).toHaveAttribute('appearance', 'filled-lighter'); + await expect(element).toHaveJSProperty('appearance', 'filled-lighter'); + }); + + test('should initialize to the `initialValue` property if no value property is set', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + const initialValue = await element.evaluate(node => node.initialValue); + + await expect(element).toHaveJSProperty('value', initialValue); + }); + + test('should initialize to the provided `value` attribute if set pre-connection', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + const element = page.locator('fluent-text-input'); + + await expect(element).toHaveJSProperty('value', 'foo'); + }); + + test('should initialize to the provided `value` property if set pre-connection', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ``; + + const textField = document.createElement('fluent-text-input') as TextInput; + + textField.value = 'foo'; + + node.appendChild(textField); + }); + + await expect(element).toHaveJSProperty('value', 'foo'); + }); + + test('should initialize to the provided `value` attribute if set post-connection', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await element.evaluate(node => { + node.setAttribute('value', 'foo'); + }); + + await expect(element).toHaveJSProperty('value', 'foo'); + }); + + test('should hide the label when no default slotted content is provided', async () => { + await root.evaluate(node => { + node.innerHTML = ''; + }); + + await expect(label).toHaveClass(/label__hidden/); + }); + + test('should hide the label when start content is provided', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + +
+
+ `; + }); + + await expect(label).toHaveClass(/label__hidden/); + }); + + test('should hide the label when end content is provided', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + +
+
+ `; + }); + + await expect(label).toHaveClass(/label__hidden/); + }); + + test('should hide the label when start and end content are provided', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + +
+
+
+ `; + }); + + await expect(label).toHaveClass(/label__hidden/); + }); + + test('should hide the label when space-only text nodes are slotted', async () => { + await root.evaluate(node => { + node.innerHTML = `\n \n`; + }); + + await expect(element).toHaveText(/\n\s\n/); + + await expect(label).toHaveClass(/label__hidden/); + }); + + test('should fire a `change` event when the internal control emits a `change` event', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + const [wasChanged] = await Promise.all([ + element.evaluate( + node => + new Promise(resolve => { + node.addEventListener('change', () => resolve(true)); + }), + ), + control.evaluate(node => { + node.dispatchEvent( + new Event('change', { + key: 'a', + } as EventInit), + ); + }), + ]); + + expect(wasChanged).toBeTruthy(); + }); + + test.describe('with a type of `password`', () => { + test('should report invalid validity when the `value` property is an empty string and `required` is true', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.valueMissing)).toBeTruthy(); + }); + + test('should report valid validity when the `value` property is a string that is non-empty and `required` is true', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.valueMissing)).toBeFalsy(); + }); + + test('should report valid validity when `value` is empty and `minlength` is set', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooShort)).toBeFalsy(); + }); + + test('should report valid validity when `value` has a length less than `minlength`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooShort)).toBeFalsy(); + }); + + test('should report valid validity when `value` is empty and `maxlength` is set', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooLong)).toBeFalsy(); + }); + + test('should report valid validity when `value` has a length which exceeds the `maxlength`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooLong)).toBeFalsy(); + }); + + test('should report valid validity when the `value` is shorter than `maxlength` and the element is `required`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooLong)).toBeFalsy(); + }); + + test('should report valid validity when the `value` property matches the `pattern` property', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.patternMismatch)).toBeFalsy(); + }); + + test('should report invalid validity when `value` does not match `pattern`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + const element = page.locator('fluent-text-input'); + + expect(await element.evaluate(node => node.validity.patternMismatch)).toBeTruthy(); + }); + }); + + test.describe('with a type of `tel`', () => { + test('should report invalid validity when the `value` property is an empty string and `required` is true', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.valueMissing)).toBeTruthy(); + }); + + test('should report valid validity when the `value` property is not empty and `required` is true', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.valueMissing)).toBeFalsy(); + }); + + test('should report valid validity when `minlength` is set and `value` is an empty string', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooShort)).toBeFalsy(); + }); + + test('should report valid validity when the length of `value` is less than `minlength`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooShort)).toBeFalsy(); + }); + + test('should report valid validity when `value` is an empty string', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooLong)).toBeFalsy(); + }); + + test('should report valid validity when `value` has a length which exceeds `maxlength`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooLong)).toBeFalsy(); + }); + + test('should report valid validity when the `value` is shorter than `maxlength` and the element is `required`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooLong)).toBeFalsy(); + }); + + test('should report valid validity when the `value` matches `pattern`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + const element = page.locator('fluent-text-input'); + + expect(await element.evaluate(node => node.validity.patternMismatch)).toBeFalsy(); + }); + + test('should report invalid validity when `value` does not match `pattern`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + const element = page.locator('fluent-text-input'); + + expect(await element.evaluate(node => node.validity.patternMismatch)).toBeTruthy(); + }); + }); + + test.describe('with a type of `text`', () => { + test('should report invalid validity when the `value` property is an empty string and `required` is true', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.valueMissing)).toBeTruthy(); + }); + + test('should report valid validity when the `value` property is not empty and `required` is true', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.valueMissing)).toBeFalsy(); + }); + + test('should report valid validity when `value` is an empty string and `minlength` is set', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooShort)).toBeFalsy(); + }); + + test('should report valid validity when `value` has a length less than `minlength`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooShort)).toBeFalsy(); + }); + + test('should report valid validity when `value` is empty and `maxlength` is set', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooLong)).toBeFalsy(); + }); + + test('should report valid validity when `value` has a length which exceeds `maxlength`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooLong)).toBeFalsy(); + }); + + test('should report valid validity when the `value` is shorter than `maxlength` and the element is `required`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.tooLong)).toBeFalsy(); + }); + + test('should report valid validity when the `value` matches `pattern`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.patternMismatch)).toBeFalsy(); + }); + + test('should report invalid validity when `value` does not match `pattern`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.patternMismatch)).toBeTruthy(); + }); + }); + + test.describe('with a type of `email`', () => { + test('should report valid validity when `value` is an empty string', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.typeMismatch)).toBeFalsy(); + }); + + test('should have invalid invalidity with a `typeMismatch` when `value` is not a valid email', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.typeMismatch)).toBeTruthy(); + }); + }); + + test.describe('with a type of `url`', () => { + test('should report valid validity when `value` is an empty string', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.typeMismatch)).toBeFalsy(); + }); + + test('should have invalid invalidity with a `typeMismatch` when `value` is not a valid URL', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + expect(await element.evaluate(node => node.validity.typeMismatch)).toBeTruthy(); + }); + }); +}); From a9991e2049eab95a699cca36925bf19ad0438c9c Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Wed, 23 Aug 2023 14:21:23 -0700 Subject: [PATCH 152/203] tabs, tab, tabpanel unit tests (#28872) * tabs tests: adds tabs, tab, and tab panel tests * tabs tests: consolidates no id tests to describe block * tabs unit tests: removes linting errors * fixes linting errors --------- Co-authored-by: Miroslav Stastny --- .../src/tab-panel/tab-panel.spec.ts | 43 ++ packages/web-components/src/tab/tab.spec.ts | 47 ++ packages/web-components/src/tabs/tabs.spec.ts | 572 ++++++++++++++++++ 3 files changed, 662 insertions(+) create mode 100644 packages/web-components/src/tab-panel/tab-panel.spec.ts create mode 100644 packages/web-components/src/tab/tab.spec.ts create mode 100644 packages/web-components/src/tabs/tabs.spec.ts diff --git a/packages/web-components/src/tab-panel/tab-panel.spec.ts b/packages/web-components/src/tab-panel/tab-panel.spec.ts new file mode 100644 index 0000000000000..2bb832f1e4e35 --- /dev/null +++ b/packages/web-components/src/tab-panel/tab-panel.spec.ts @@ -0,0 +1,43 @@ +import type { Locator, Page } from '@playwright/test'; +import { expect, test } from '@playwright/test'; +import { fixtureURL } from '../helpers.tests.js'; + +test.describe('TabPanel', () => { + let page: Page; + let element: Locator; + let root: Locator; + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + + element = page.locator('fluent-tab-panel'); + + root = page.locator('#root'); + + await page.goto(fixtureURL('components-tabs--tabs-default')); + }); + + test.afterAll(async () => { + await page.close(); + }); + + test('should have a role of `tabpanel`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(element).toHaveAttribute('role', 'tabpanel'); + }); + + test('should have a slot attribute of `tabpanel`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(element).toHaveAttribute('slot', 'tabpanel'); + }); +}); diff --git a/packages/web-components/src/tab/tab.spec.ts b/packages/web-components/src/tab/tab.spec.ts new file mode 100644 index 0000000000000..cf011d0920a28 --- /dev/null +++ b/packages/web-components/src/tab/tab.spec.ts @@ -0,0 +1,47 @@ +import type { Locator, Page } from '@playwright/test'; +import { expect, test } from '@playwright/test'; +import { fixtureURL } from '../helpers.tests.js'; +import type { Tab } from './tab.js'; + +test.describe('Tab', () => { + test.describe('States, attributes, and properties', () => { + let page: Page; + let element: Locator; + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + + await page.goto(fixtureURL('components-tabs--tabs-default')); + + element = page.locator('fluent-tab').nth(0); + }); + + test.afterAll(async () => { + await page.close(); + }); + + test('should have a role of `tab`', async () => { + await expect(element).toHaveAttribute('role', 'tab'); + }); + + test('should have a slot attribute of `tab`', async () => { + await expect(element).toHaveAttribute('slot', 'tab'); + }); + + test('should set the `aria-disabled` attribute when `disabled` is true', async () => { + await expect(element).not.toHaveAttribute('aria-disabled', ''); + + await element.nth(0).evaluate(node => { + node.disabled = true; + }); + + await expect(element).toHaveAttribute('aria-disabled', 'true'); + + await element.nth(0).evaluate(element => { + element.disabled = false; + }); + + await expect(element).toHaveAttribute('aria-disabled', 'false'); + }); + }); +}); diff --git a/packages/web-components/src/tabs/tabs.spec.ts b/packages/web-components/src/tabs/tabs.spec.ts new file mode 100644 index 0000000000000..f0f35da4cdeb4 --- /dev/null +++ b/packages/web-components/src/tabs/tabs.spec.ts @@ -0,0 +1,572 @@ +import type { Locator, Page } from '@playwright/test'; +import { expect, test } from '@playwright/test'; +import { fixtureURL } from '../helpers.tests.js'; +import type { Tab } from '../tab/tab.js'; +import type { Tabs } from './tabs.js'; + +test.describe('Tabs', () => { + let page: Page; + let element: Locator; + let root: Locator; + let tablist: Locator; + let tabs: Locator; + + const template = /* html */ ` + + Tab one + Tab two + Tab three + Tab panel one + Tab panel two + Tab panel three + + `; + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + + element = page.locator('fluent-tabs'); + + root = page.locator('#root'); + + tablist = element.locator('.tablist'); + + tabs = element.locator('fluent-tab'); + + await page.goto(fixtureURL('components-tabs--tabs-default')); + }); + + test.afterAll(async () => { + await page.close(); + }); + + test('should reset tab indicator offset and scale for horizontal orientation after animation', async () => { + await root.evaluate( + (node, { template }) => { + node.innerHTML = template; + }, + { template }, + ); + + const tab = tabs.nth(2); + await tab.click(); + + const tabIndicatorValues = await page.evaluate(() => { + const tabsElement = document.querySelector('fluent-tabs') as Element; + return { + offset: getComputedStyle(tabsElement).getPropertyValue('--tabIndicatorOffset').trim(), + scale: getComputedStyle(tabsElement).getPropertyValue('--tabIndicatorScale').trim(), + }; + }); + + expect(tabIndicatorValues.offset).toBe('0px'); + expect(tabIndicatorValues.scale).toBe('1'); + }); + + test('should animate the active tab indicator', async () => { + await root.evaluate( + (node, { template }) => { + node.innerHTML = template; + }, + { template }, + ); + + const tab = tabs.nth(2); + + const valueBeforeClick = await page.evaluate(() => { + const tabElement = document.querySelector('fluent-tab:nth-child(3)') as Element; + return tabElement.getAttribute('data-animate'); + }); + + expect(valueBeforeClick).toBe(null); + + await tab.click(); + + const valueAfterClick = await page.evaluate(() => { + const tabElement = document.querySelector('fluent-tab:nth-child(3)') as Element; + return tabElement.getAttribute('data-animate'); + }); + + expect(valueAfterClick).toBe('true'); + }); + + test('should have reflect disabled attribute on control', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + await expect(element).not.toHaveAttribute('disabled', ''); + + await element.evaluate((node: Tabs) => { + node.disabled = true; + }); + + await expect(element).toHaveAttribute('disabled', ''); + }); + + test('should have an internal element with a role of `tablist`', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(tablist).toHaveAttribute('role', 'tablist'); + }); + + test('should set a default orientation value of `horizontal` when `orientation` is not provided', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(element).toHaveJSProperty('orientation', 'horizontal'); + }); + + test('should set an `id` attribute on the active tab when an `id` is provided', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + const tabCount = await tabs.count(); + + for (let i = 0; i < tabCount; i++) { + const tab = tabs.nth(i); + + await tab.evaluate((node, i) => { + node.id = `custom-id-${i}`; + }, i); + + await expect(tab).toHaveAttribute('id', `custom-id-${i}`); + } + }); + + test.describe('`id` NOT provided', () => { + test('should set an `id` attribute on tab items with a unique ID when an `id` is NOT provided', async () => { + await root.evaluate( + (node, { template }) => { + node.innerHTML = template; + }, + { template }, + ); + + const tabCount = await tabs.count(); + + for (let i = 0; i < tabCount; i++) { + const tab = tabs.nth(i); + + const id = await tab.getAttribute('id'); + + // The ID function may not start at 0 so we need to check that the ID is unique + expect(id).toMatch(/tab-\d+/); + + const tabPanel = element.locator(`#${id}`); + + await expect(tabPanel).toHaveCount(1); + } + }); + + test('should set `aria-labelledby` on the tab panel and `aria-controls` on the tab which corresponds to the matching ID when IDs are NOT provided', async () => { + await root.evaluate( + (node, { template }) => { + node.innerHTML = template; + }, + { template }, + ); + + const tabCount = await tabs.count(); + + for (let i = 0; i < tabCount; i++) { + const tab = tabs.nth(i); + + const panelId = (await tab.getAttribute('aria-controls')) as string; + + expect(panelId).toMatch(/panel-\d+/); + + const tabPanel = element.locator(`#${panelId}`); + + await expect(tabPanel).toHaveCount(1); + + const tabId = (await tab.getAttribute('id')) as string; + + expect(tabId).toMatch(/tab-\d+/); + + await expect(tabPanel).toHaveAttribute('aria-labelledby', tabId); + + await expect(tab).toHaveAttribute('aria-controls', panelId); + } + }); + + test('should set `aria-labelledby` on the tab panel and `aria-controls` on the tab which corresponds to the matching ID when IDs are NOT provided and additional tabs and panels are added', async () => { + await root.evaluate( + (node, { template }) => { + node.innerHTML = template; + }, + { template }, + ); + + let tabCount = await tabs.count(); + + for (let i = 0; i < tabCount; i++) { + const tab = tabs.nth(i); + + const panelId = (await tab.getAttribute('aria-controls')) as string; + + expect(panelId).toMatch(/panel-\d+/); + + const tabPanel = element.locator(`#${panelId}`); + + await expect(tabPanel).toHaveCount(1); + + const tabId = (await tab.getAttribute('id')) as string; + + expect(tabId).toMatch(/tab-\d+/); + + await expect(tabPanel).toHaveAttribute('aria-labelledby', tabId); + + await expect(tab).toHaveAttribute('aria-controls', panelId); + } + + await element.evaluate(node => { + const tabs = Array.from(node.querySelectorAll('fluent-tab')); + + const newTab = document.createElement('fluent-tab'); + newTab.textContent = 'New Tab'; + node.insertBefore(newTab, tabs[1]); + + const newPanel = document.createElement('fluent-tab-panel'); + newPanel.textContent = 'New Panel'; + node.insertBefore(newPanel, tabs[1]); + }); + + tabCount = await tabs.count(); + + for (let i = 0; i < tabCount; i++) { + const tab = tabs.nth(i); + + const panelId = (await tab.getAttribute('aria-controls')) as string; + + expect(panelId).toMatch(/panel-\d+/); + + const tabPanel = element.locator(`#${panelId}`); + + await expect(tabPanel).toHaveCount(1); + + const tabId = (await tab.getAttribute('id')) as string; + + expect(tabId).toMatch(/tab-\d+/); + + await expect(tabPanel).toHaveAttribute('aria-labelledby', tabId); + + await expect(tab).toHaveAttribute('aria-controls', panelId); + } + }); + + test('should default the first tab as the active index if `activeid` is NOT provided', async () => { + await root.evaluate( + (node, { template }) => { + node.innerHTML = template; + }, + { template }, + ); + + await expect(tabs.nth(0)).toHaveAttribute('aria-selected', 'true'); + + await expect(element).toHaveJSProperty('activeTabIndex', 0); + }); + }); + + test.describe('active tab', () => { + test('should set an `aria-selected` attribute on the active tab when `activeid` is provided', async () => { + await root.evaluate( + (node, { template }) => { + node.innerHTML = template; + }, + { template }, + ); + + const secondTab = tabs.nth(1); + + const secondTabId = `${await secondTab.getAttribute('id')}`; + + await element.evaluate((node: Tabs, secondTabId) => { + node.activeid = secondTabId; + }, secondTabId); + + await expect(secondTab).toHaveAttribute('aria-selected', 'true'); + }); + + test('should update `aria-selected` attribute on the active tab when `activeId` is updated', async () => { + await root.evaluate( + (node, { template }) => { + node.innerHTML = template; + }, + { template }, + ); + + await expect(tabs.nth(0)).toHaveAttribute('aria-selected', 'true'); + + const secondTab = tabs.nth(1); + + const secondTabId = `${await secondTab.getAttribute('id')}`; + + await element.evaluate((node: Tabs, secondTabId) => { + node.setAttribute('activeId', secondTabId); + }, secondTabId); + + await expect(secondTab).toHaveAttribute('aria-selected', 'true'); + }); + }); + + test.describe('active tabpanel', () => { + test('should set an `aria-labelledby` attribute on the tabpanel with a value of the tab id when `activeid` is provided', async () => { + await root.evaluate( + (node, { template }) => { + node.innerHTML = template; + }, + { template }, + ); + + const secondTab = tabs.nth(1); + + const secondTabId = `${await secondTab.getAttribute('id')}`; + + const tabPanels = element.locator('fluent-tab-panel'); + + await element.evaluate((node: Tabs, secondTabId) => { + node.activeid = secondTabId; + }, secondTabId); + + await expect(tabPanels.nth(1)).toHaveAttribute('aria-labelledby', secondTabId); + }); + + test('should set an attribute of hidden if the tabpanel is not active', async () => { + await root.evaluate( + (node, { template }) => { + node.innerHTML = template; + }, + { template }, + ); + + const tabPanels = element.locator('fluent-tab-panel'); + + await expect(tabPanels.nth(0)).not.toHaveAttribute('hidden', ''); + + await expect(tabPanels.nth(1)).toHaveAttribute('hidden', ''); + + await expect(tabPanels.nth(2)).toHaveAttribute('hidden', ''); + }); + }); + + test('should reflect appearance attribute values', async () => { + await element.evaluate((node: Tabs) => { + node.appearance = 'subtle'; + }); + await expect(element).toHaveAttribute('appearance', 'subtle'); + await expect(element).toHaveJSProperty('appearance', 'subtle'); + + await element.evaluate((node: Tabs) => { + node.appearance = 'transparent'; + }); + await expect(element).toHaveAttribute('appearance', 'transparent'); + await expect(element).toHaveJSProperty('appearance', 'transparent'); + }); + + test('should reflect size attribute values', async () => { + await element.evaluate((node: Tabs) => { + node.size = 'small'; + }); + await expect(element).toHaveAttribute('size', 'small'); + await expect(element).toHaveJSProperty('size', 'small'); + + await element.evaluate((node: Tabs) => { + node.size = 'medium'; + }); + await expect(element).toHaveAttribute('size', 'medium'); + await expect(element).toHaveJSProperty('size', 'medium'); + + await element.evaluate((node: Tabs) => { + node.size = 'large'; + }); + await expect(element).toHaveAttribute('size', 'large'); + await expect(element).toHaveJSProperty('size', 'large'); + }); + + test('should not allow selecting a tab that has been disabled after it has been connected', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Tab one + Tab two + Tab three + Tab panel one + Tab panel two + Tab panel three + + `; + }); + + await (await element.elementHandle())?.waitForElementState('stable'); + + const firstTab = tabs.nth(0); + + const firstTabId = await firstTab.getAttribute('id'); + + expect(firstTabId).toBe('tab-1'); + + await element.evaluate((node: Tabs, firstTabId) => { + node.activeid = `${firstTabId}`; + }, firstTabId); + + await (await element.elementHandle())?.waitForElementState('stable'); + + await expect(element).toHaveJSProperty('activeid', firstTabId); + + const secondTab = tabs.nth(1); + + await secondTab.evaluate((node: Tab) => { + node.disabled = true; + }); + + await (await element.elementHandle())?.waitForElementState('stable'); + + await secondTab.evaluate(node => { + node.dispatchEvent( + new MouseEvent('click', { + bubbles: true, + cancelable: true, + view: window, + }), + ); + }); + + await expect(element).toHaveJSProperty('activeid', firstTabId); + }); + + test('should allow selecting tab that has been enabled after it has been connected', async () => { + test.slow(); + + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Tab one + Tab two + Tab three + Tab panel one + Tab panel two + Tab panel three + + `; + }); + + const firstTab = tabs.nth(0); + + const secondTab = tabs.nth(1); + + const firstTabId = `${await firstTab.getAttribute('id')}`; + const secondTabId = `${await secondTab.getAttribute('id')}`; + + await element.evaluate((node: Tabs, firstTabId) => { + node.activeid = firstTabId; + }, firstTabId); + + await expect(element).toHaveJSProperty('activeid', firstTabId); + + await secondTab.evaluate(node => { + node.dispatchEvent( + new MouseEvent('click', { + bubbles: true, + cancelable: true, + view: window, + }), + ); + }); + + await expect(element).toHaveJSProperty('activeid', firstTabId); + + await secondTab.evaluate((node: Tab) => { + node.disabled = false; + }); + + await (await element.elementHandle())?.waitForElementState('stable'); + + await secondTab.evaluate(node => { + node.dispatchEvent( + new MouseEvent('click', { + bubbles: true, + cancelable: true, + view: window, + }), + ); + }); + await expect(element).toHaveJSProperty('activeid', secondTabId); + }); + + test('should not allow selecting hidden tab using arrow keys', async () => { + test.slow(); + + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Tab one + + Tab three + Tab panel one + Tab panel two + Tab panel three + + `; + }); + + const firstTab = tabs.nth(0); + + const thirdTab = tabs.nth(2); + + const firstTabId = `${await firstTab.getAttribute('id')}`; + const thirdTabId = `${await thirdTab.getAttribute('id')}`; + + await element.evaluate((node: Tabs, firstTabId) => { + node.activeid = firstTabId; + }, firstTabId); + + await firstTab.press('ArrowRight'); + + await expect(element).toHaveJSProperty('activeid', thirdTabId); + }); + + test('should not allow selecting hidden tab by pressing End', async () => { + test.slow(); + + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Tab one + Tab two + + Tab panel one + Tab panel two + Tab panel three + + `; + }); + + const firstTab = tabs.nth(0); + + const secondTab = tabs.nth(1); + + const firstTabId = `${await firstTab.getAttribute('id')}`; + const secondTabId = `${await secondTab.getAttribute('id')}`; + + await element.evaluate((node: Tabs, firstTabId) => { + node.activeid = firstTabId; + }, firstTabId); + + await firstTab.press('End'); + + await expect(element).toHaveJSProperty('activeid', secondTabId); + }); +}); From 895d6e7af74ece7f5bd7ad76d139effdad835364 Mon Sep 17 00:00:00 2001 From: Hale Rankin Date: Wed, 23 Aug 2023 22:07:59 -0700 Subject: [PATCH 153/203] Adds Tests For Fluent Image Web Component (#28815) * Adds playwright tests for Image component. * Breaks tests into discrete chunks allowing for evaluation of each attribute. * Removes unused import from Checkbox story. Passes linting. --------- Co-authored-by: Miroslav Stastny --- .../web-components/src/image/image.spec.ts | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 packages/web-components/src/image/image.spec.ts diff --git a/packages/web-components/src/image/image.spec.ts b/packages/web-components/src/image/image.spec.ts new file mode 100644 index 0000000000000..c23ab7fe4a6f3 --- /dev/null +++ b/packages/web-components/src/image/image.spec.ts @@ -0,0 +1,126 @@ +import { expect, test } from '@playwright/test'; +import type { Locator, Page } from '@playwright/test'; +import { fixtureURL } from '../helpers.tests.js'; +import type { Image } from './image.js'; + +test.describe('Image', () => { + let page: Page; + let element: Locator; + let root: Locator; + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + element = page.locator('fluent-image'); + root = page.locator('#root'); + await page.goto(fixtureURL('components-image--image')); + }); + + test.afterAll(async () => { + await page.close(); + }); + + test('should initialize to the `block` attribute', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Short image description + + `; + }); + + await expect(element).toHaveJSProperty('block', true); + + await element.evaluate((node: Image) => { + node.block = false; + }); + await expect(element).not.toHaveJSProperty('block', true); + }); + + test('should initialize to the `bordered` attribute', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Short image description + + `; + }); + + await expect(element).toHaveJSProperty('bordered', true); + + await element.evaluate((node: Image) => { + node.bordered = undefined; + }); + await expect(element).not.toHaveJSProperty('bordered', true); + }); + + test('should initialize to the `shadow` attribute', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Short image description + + `; + }); + + await expect(element).toHaveJSProperty('shadow', true); + + await element.evaluate((node: Image) => { + node.shadow = undefined; + }); + await expect(element).not.toHaveJSProperty('shadow', true); + }); + + test('should initialize to the `fit` attribute', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Short image description + + `; + }); + + await expect(element).toHaveJSProperty('fit', 'default'); + + await element.evaluate((node: Image) => { + node.fit = 'none'; + }); + await expect(element).toHaveJSProperty('fit', 'none'); + + await element.evaluate((node: Image) => { + node.fit = 'center'; + }); + await expect(element).toHaveJSProperty('fit', 'center'); + + await element.evaluate((node: Image) => { + node.fit = 'contain'; + }); + await expect(element).toHaveJSProperty('fit', 'contain'); + + await element.evaluate((node: Image) => { + node.fit = 'cover'; + }); + await expect(element).toHaveJSProperty('fit', 'cover'); + }); + + test('should initialize to the `shape` attribute', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + Short image description + + `; + }); + + await expect(element).toHaveJSProperty('shape', 'circular'); + + await element.evaluate((node: Image) => { + node.shape = 'rounded'; + }); + await expect(element).toHaveJSProperty('shape', 'rounded'); + + await element.evaluate((node: Image) => { + node.shape = 'square'; + }); + await expect(element).toHaveJSProperty('shape', 'square'); + }); +}); From c7eacb263cd661aef3e3e4a5331eb64eb84bc0b0 Mon Sep 17 00:00:00 2001 From: Hale Rankin Date: Wed, 23 Aug 2023 22:10:48 -0700 Subject: [PATCH 154/203] Adds Tests For Fluent Anchor Button Web Component (#28825) * Completes Anchor Button tests. * Updates tests to prevent flaky results. Fixes boolean tests. Passes linter. --- .../src/anchor-button/anchor-button.spec.ts | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 packages/web-components/src/anchor-button/anchor-button.spec.ts diff --git a/packages/web-components/src/anchor-button/anchor-button.spec.ts b/packages/web-components/src/anchor-button/anchor-button.spec.ts new file mode 100644 index 0000000000000..250358636ae36 --- /dev/null +++ b/packages/web-components/src/anchor-button/anchor-button.spec.ts @@ -0,0 +1,106 @@ +import { spinalCase } from '@microsoft/fast-web-utilities'; +import { expect, test } from '@playwright/test'; +import type { Locator, Page } from '@playwright/test'; +import { fixtureURL } from '../helpers.tests.js'; + +// Regular Attributes +const attributes = { + appearance: 'primary', + shape: 'rounded', + size: 'medium', + href: 'href', + ping: 'ping', + hreflang: 'en-GB', + referrerpolicy: 'no-referrer', + rel: 'external', + target: '_blank', + type: 'foo', + ariaControls: 'testId', + ariaCurrent: 'page', + ariaDescribedby: 'testId', + ariaDetails: 'testId', + ariaErrormessage: 'test', + ariaFlowto: 'testId', + ariaInvalid: 'spelling', + ariaKeyshortcuts: 'F4', + ariaLabel: 'foo', + ariaLabelledby: 'testId', + ariaLive: 'polite', + ariaOwns: 'testId', + ariaRelevant: 'removals', + ariaRoledescription: 'slide', +}; + +// Boolean Attributes +const booleanAttributes = { + iconOnly: true, + disabled: true, + disabledFocusable: true, + ariaAtomic: true, + ariaBusy: false, + ariaDisabled: true, + ariaExpanded: true, + ariaHaspopup: true, + ariaHidden: true, +}; + +test.describe('Anchor Button - Regular Attributes', () => { + let page: Page; + let element: Locator; + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + await page.goto(fixtureURL('components-button-anchor--anchor-button', attributes)); + element = page.locator('fluent-anchor-button'); + }); + + test.afterAll(async () => { + await page.close(); + }); + + for (const [attribute, value] of Object.entries(attributes)) { + const attributeSpinalCase = spinalCase(attribute); + + test(`should set the regular attribute: \`${attributeSpinalCase}\` to \`${value}\` on the internal control`, async () => { + await element.evaluate( + (node: any, { attribute, value }) => { + node.setAttribute(attribute, value); + }, + { attribute: attributeSpinalCase, value }, + ); + + await expect(element).toHaveJSProperty(`${attribute}`, `${value}`); + }); + } +}); + +test.describe('Anchor Button - Boolean Attributes', () => { + let page: Page; + let element: Locator; + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + await page.goto(fixtureURL('components-button-anchor--anchor-button', booleanAttributes)); + element = page.locator('fluent-anchor-button'); + }); + + test.afterAll(async () => { + await page.close(); + }); + + // Boolean attributes + for (const [attribute, value] of Object.entries(booleanAttributes)) { + const attributeSpinalCase = spinalCase(attribute); + + test(`should set the boolean attribute: \`${attributeSpinalCase}\` to \`${value}\``, async () => { + await element.evaluate( + (node: any, { attribute, value }) => { + node[attribute] = value; + }, + { attribute, value }, + ); + + await expect(element).toHaveJSProperty(attribute, value); + }); + } +}); From 75c3982af53d5d5d712c8cfe7c663e9407afd4c6 Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Wed, 23 Aug 2023 22:17:03 -0700 Subject: [PATCH 155/203] avatar unit tests (#28800) * radio init * styles radio * reverts branch * input spec init * cleans up spec * formatting * updates component name to text input * updates component name in spec * reverts dead file * avatar unit tests: adds tests * avatar tests: updates tests * avatar unit tests: updates tests * fix lint errors * fixes linting errors --------- Co-authored-by: Miroslav Stastny --- .../web-components/src/avatar/avatar.spec.ts | 205 ++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 packages/web-components/src/avatar/avatar.spec.ts diff --git a/packages/web-components/src/avatar/avatar.spec.ts b/packages/web-components/src/avatar/avatar.spec.ts new file mode 100644 index 0000000000000..5fab067f8ba0d --- /dev/null +++ b/packages/web-components/src/avatar/avatar.spec.ts @@ -0,0 +1,205 @@ +import { expect, test } from '@playwright/test'; +import type { Locator, Page } from '@playwright/test'; +import { fixtureURL } from '../helpers.tests.js'; +import { Avatar } from './avatar.js'; +import { AvatarAppearance, AvatarColor, AvatarSize } from './avatar.options.js'; + +test.describe('Avatar Component', () => { + let page: Page; + let element: Locator; + let root: Locator; + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + + element = page.locator('fluent-avatar'); + + root = page.locator('#root'); + + await page.goto(fixtureURL('components-avatar--avatar')); + }); + + test.afterAll(async () => { + await page.close(); + }); + + const colorAttributes = { + neutral: 'neutral', + brand: 'brand', + colorful: 'colorful', + darkRed: 'dark-red', + cranberry: 'cranberry', + red: 'red', + pumpkin: 'pumpkin', + peach: 'peach', + marigold: 'marigold', + gold: 'gold', + brass: 'brass', + brown: 'brown', + forest: 'forest', + seafoam: 'seafoam', + darkGreen: 'dark-green', + lightTeal: 'light-teal', + teal: 'teal', + steel: 'steel', + blue: 'blue', + royalBlue: 'royal-blue', + cornflower: 'cornflower', + navy: 'navy', + lavender: 'lavender', + purple: 'purple', + grape: 'grape', + lilac: 'lilac', + pink: 'pink', + magenta: 'magenta', + plum: 'plum', + beige: 'beige', + mink: 'mink', + platinum: 'platinum', + anchor: 'anchor', + }; + + const appearanceAttributes = { + ring: 'ring', + shadow: 'shadow', + ringShadow: 'ring-shadow', + }; + + const sizeAttributes = { + _16: 16, + _20: 20, + _24: 24, + _28: 28, + _32: 32, + _36: 36, + _40: 40, + _48: 48, + _56: 56, + _64: 64, + _72: 72, + _96: 96, + _120: 120, + _128: 128, + }; + + test('should render without crashing', async () => { + await page.waitForSelector('fluent-avatar'); + await expect(element).toBeVisible(); + }); + + test('When no name value is set, should render with custom initials based on the provided initials value', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(element).toHaveText('JD'); + }); + + test('When name value is set, should generate initials based on the provided name value', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(element).toHaveText('JD'); + }); + + test('When name value and custom initials are set, should prioritize the provided initials', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(element).toHaveText('JJ'); + }); + + test('should render correctly in active state', async () => { + await element.evaluate((node: Avatar) => { + node.active = 'active'; + }); + + await expect(element).toHaveJSProperty('active', 'active'); + }); + + test('should render correctly in inactive state', async () => { + await element.evaluate((node: Avatar) => { + node.active = 'inactive'; + }); + + await expect(element).toHaveJSProperty('active', 'inactive'); + }); + + test('default color should be neutral', async () => { + await expect(element).toHaveAttribute('data-color', `neutral`); + }); + + test('should default to a specific color when "colorful" is set without name or colorId', async () => { + await element.evaluate((node: Avatar) => { + node.color = 'colorful'; + }); + const generatedColor = await element.evaluate((node: Avatar) => { + return node.generateColor(); + }); + await expect(element).toHaveAttribute('data-color', `${generatedColor}`); + }); + + test('should derive the color from the name attribute when set to "colorful"', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + const generatedColor = await element.evaluate((node: Avatar) => { + return node.generateColor(); + }); + + await expect(element).toHaveAttribute('data-color', `${generatedColor}`); + }); + + test('should prioritize color derivation from colorId over name when set to "colorful"', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + const generatedColor = await element.evaluate((node: Avatar) => { + return node.generateColor(); + }); + await expect(element).toHaveAttribute('data-color', `${generatedColor}`); + }); + + for (const [, value] of Object.entries(colorAttributes)) { + test(`should set the color attribute to \`${value}\` on the internal control`, async () => { + await element.evaluate((node: Avatar, colorValue: string) => { + node.color = colorValue as AvatarColor; + }, value as string); + await expect(element).toHaveJSProperty('color', `${value}`); + await expect(element).toHaveAttribute('color', `${value}`); + }); + } + for (const [, value] of Object.entries(sizeAttributes)) { + test(`should set the size attribute to \`${value}\` on the internal control`, async () => { + await element.evaluate((node: Avatar, sizeValue: number) => { + node.size = sizeValue as AvatarSize; + }, value as number); + await expect(element).toHaveJSProperty('size', value); + await expect(element).toHaveAttribute('size', `${value}`); + }); + } + for (const [, value] of Object.entries(appearanceAttributes)) { + test(`should set and reflect the appearance attribute to \`${value}\` on the internal control`, async () => { + await element.evaluate((node: Avatar, appearanceValue: string) => { + node.appearance = appearanceValue as AvatarAppearance; + }, value as string); + + await expect(element).toHaveJSProperty('appearance', `${value}`); + await expect(element).toHaveAttribute('appearance', `${value}`); + }); + } +}); From 920db2bd384cf288e5a1c25f292ab7e6ac56b14f Mon Sep 17 00:00:00 2001 From: Miroslav Stastny Date: Thu, 24 Aug 2023 15:55:17 -0700 Subject: [PATCH 156/203] feat: Bump version to beta (#28976) * feat: Bump version to beta * change file * fix vr test deps --- apps/vr-tests-web-components/package.json | 2 +- ...eb-components-2f4b6058-a642-437e-adf0-85fdeb5fe68c.json | 7 +++++++ packages/web-components/package.json | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 change/@fluentui-web-components-2f4b6058-a642-437e-adf0-85fdeb5fe68c.json diff --git a/apps/vr-tests-web-components/package.json b/apps/vr-tests-web-components/package.json index 45b562856bb2e..835faeb8e8ac9 100644 --- a/apps/vr-tests-web-components/package.json +++ b/apps/vr-tests-web-components/package.json @@ -23,7 +23,7 @@ "dependencies": { "@fluentui/react-button": "^9.2.3", "@fluentui/react-storybook-addon": "*", - "@fluentui/web-components": "3.0.0-alpha.31", + "@fluentui/web-components": "3.0.0-beta.0", "tslib": "^2.1.0" } } diff --git a/change/@fluentui-web-components-2f4b6058-a642-437e-adf0-85fdeb5fe68c.json b/change/@fluentui-web-components-2f4b6058-a642-437e-adf0-85fdeb5fe68c.json new file mode 100644 index 0000000000000..15f8ec0d1bc60 --- /dev/null +++ b/change/@fluentui-web-components-2f4b6058-a642-437e-adf0-85fdeb5fe68c.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Bump version to beta", + "packageName": "@fluentui/web-components", + "email": "miroslav.stastny@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 8da56e64289b0..85d5fbf5dc60f 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -1,7 +1,7 @@ { "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", - "version": "3.0.0-alpha.31", + "version": "3.0.0-beta.0", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" @@ -203,6 +203,6 @@ "minor", "patch" ], - "tag": "alpha" + "tag": "beta" } } From 88406da5ea9748f9d00cbee4de53888ba274dd2c Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Fri, 25 Aug 2023 04:19:44 +0000 Subject: [PATCH 157/203] applying package updates --- apps/vr-tests-web-components/package.json | 2 +- ...ents-2f4b6058-a642-437e-adf0-85fdeb5fe68c.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 5 files changed, 27 insertions(+), 10 deletions(-) delete mode 100644 change/@fluentui-web-components-2f4b6058-a642-437e-adf0-85fdeb5fe68c.json diff --git a/apps/vr-tests-web-components/package.json b/apps/vr-tests-web-components/package.json index 835faeb8e8ac9..a71d93d9f2e63 100644 --- a/apps/vr-tests-web-components/package.json +++ b/apps/vr-tests-web-components/package.json @@ -23,7 +23,7 @@ "dependencies": { "@fluentui/react-button": "^9.2.3", "@fluentui/react-storybook-addon": "*", - "@fluentui/web-components": "3.0.0-beta.0", + "@fluentui/web-components": "3.0.0-beta.1", "tslib": "^2.1.0" } } diff --git a/change/@fluentui-web-components-2f4b6058-a642-437e-adf0-85fdeb5fe68c.json b/change/@fluentui-web-components-2f4b6058-a642-437e-adf0-85fdeb5fe68c.json deleted file mode 100644 index 15f8ec0d1bc60..0000000000000 --- a/change/@fluentui-web-components-2f4b6058-a642-437e-adf0-85fdeb5fe68c.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "Bump version to beta", - "packageName": "@fluentui/web-components", - "email": "miroslav.stastny@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index de334a06c8bb6..6e784210ce751 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Fri, 25 Aug 2023 04:19:39 GMT", + "tag": "@fluentui/web-components_v3.0.0-beta.1", + "version": "3.0.0-beta.1", + "comments": { + "prerelease": [ + { + "author": "miroslav.stastny@microsoft.com", + "package": "@fluentui/web-components", + "commit": "c271ab35c7160288de81b27a31627aa199a9afe3", + "comment": "Bump version to beta" + } + ] + } + }, { "date": "Wed, 23 Aug 2023 04:18:01 GMT", "tag": "@fluentui/web-components_v3.0.0-alpha.31", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index cd7baad3fde8a..6ad0eeaf459e0 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Wed, 23 Aug 2023 04:18:01 GMT and should not be manually modified. +This log was last generated on Fri, 25 Aug 2023 04:19:39 GMT and should not be manually modified. +## [3.0.0-beta.1](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-beta.1) + +Fri, 25 Aug 2023 04:19:39 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-alpha.31..@fluentui/web-components_v3.0.0-beta.1) + +### Changes + +- Bump version to beta ([PR #28976](https://github.com/microsoft/fluentui/pull/28976) by miroslav.stastny@microsoft.com) + ## [3.0.0-alpha.31](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-alpha.31) Wed, 23 Aug 2023 04:18:01 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 85d5fbf5dc60f..9ddf5955c145a 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -1,7 +1,7 @@ { "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", - "version": "3.0.0-beta.0", + "version": "3.0.0-beta.1", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 6f6042dca258f88386bb9328fb911f64ffa4bd16 Mon Sep 17 00:00:00 2001 From: Mohamed Mansour Date: Fri, 25 Aug 2023 12:10:39 -0700 Subject: [PATCH 158/203] fix(web-components): Fixed pathing to types for package exports (#28986) Running typescript typechecking threw an error that it cannot find the type for the import defined in the package exports. This change updates package.json to point to the right location, dts folder, instead of esm folder. Co-authored-by: Chris Holt --- ...-663811d0-6bde-44e5-8dc2-9857aea867db.json | 7 +++ packages/web-components/package.json | 56 +++++++++---------- 2 files changed, 35 insertions(+), 28 deletions(-) create mode 100644 change/@fluentui-web-components-663811d0-6bde-44e5-8dc2-9857aea867db.json diff --git a/change/@fluentui-web-components-663811d0-6bde-44e5-8dc2-9857aea867db.json b/change/@fluentui-web-components-663811d0-6bde-44e5-8dc2-9857aea867db.json new file mode 100644 index 0000000000000..785edb865d4d2 --- /dev/null +++ b/change/@fluentui-web-components-663811d0-6bde-44e5-8dc2-9857aea867db.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Fixed pathing to types for package exports", + "packageName": "@fluentui/web-components", + "email": "mmansour@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 9ddf5955c145a..bb3bbecc535f9 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -24,115 +24,115 @@ "default": "./dist/esm/index.js" }, "./accordion.js": { - "types": "./dist/esm/accordion/define.d.ts", + "types": "./dist/dts/accordion/define.d.ts", "default": "./dist/esm/accordion/define.js" }, "./accordion-item.js": { - "types": "./dist/esm/accordion-item/define.d.ts", + "types": "./dist/dts/accordion-item/define.d.ts", "default": "./dist/esm/accordion-item/define.js" }, "./anchor-button.js": { - "types": "./dist/esm/anchor-button/define.d.ts", + "types": "./dist/dts/anchor-button/define.d.ts", "default": "./dist/esm/anchor-button/define.js" }, "./avatar.js": { - "types": "./dist/esm/avatar/define.d.ts", + "types": "./dist/dts/avatar/define.d.ts", "default": "./dist/esm/avatar/define.js" }, "./badge.js": { - "types": "./dist/esm/badge/define.d.ts", + "types": "./dist/dts/badge/define.d.ts", "default": "./dist/esm/badge/define.js" }, "./button.js": { - "types": "./dist/esm/button/define.d.ts", + "types": "./dist/dts/button/define.d.ts", "default": "./dist/esm/button/define.js" }, "./checkbox.js": { - "types": "./dist/esm/checkbox/define.d.ts", + "types": "./dist/dts/checkbox/define.d.ts", "default": "./dist/esm/checkbox/define.js" }, "./compound-button.js": { - "types": "./dist/esm/compound-button/define.d.ts", + "types": "./dist/dts/compound-button/define.d.ts", "default": "./dist/esm/compound-button/define.js" }, "./counter-badge.js": { - "types": "./dist/esm/counter-badge/define.d.ts", + "types": "./dist/dts/counter-badge/define.d.ts", "default": "./dist/esm/counter-badge/define.js" }, "./divider.js": { - "types": "./dist/esm/divider/define.d.ts", + "types": "./dist/dts/divider/define.d.ts", "default": "./dist/esm/divider/define.js" }, "./image.js": { - "types": "./dist/esm/image/define.d.ts", + "types": "./dist/dts/image/define.d.ts", "default": "./dist/esm/image/define.js" }, "./label.js": { - "types": "./dist/esm/label/define.d.ts", + "types": "./dist/dts/label/define.d.ts", "default": "./dist/esm/label/define.js" }, "./menu-list.js": { - "types": "./dist/esm/menu-list/define.d.ts", + "types": "./dist/dts/menu-list/define.d.ts", "default": "./dist/esm/menu-list/define.js" }, "./menu-button.js": { - "types": "./dist/esm/menu-button/define.d.ts", + "types": "./dist/dts/menu-button/define.d.ts", "default": "./dist/esm/menu-button/define.js" }, "./menu-item.js": { - "types": "./dist/esm/menu-item/define.d.ts", + "types": "./dist/dts/menu-item/define.d.ts", "default": "./dist/esm/menu-item/define.js" }, "./progress-bar.js": { - "types": "./dist/esm/progress-bar/define.d.ts", + "types": "./dist/dts/progress-bar/define.d.ts", "default": "./dist/esm/progress-bar/define.js" }, "./radio.js": { - "types": "./dist/esm/radio/define.d.ts", + "types": "./dist/dts/radio/define.d.ts", "default": "./dist/esm/radio/define.js" }, "./radio-group.js": { - "types": "./dist/esm/radio-group/define.d.ts", + "types": "./dist/dts/radio-group/define.d.ts", "default": "./dist/esm/radio-group/define.js" }, "./slider.js": { - "types": "./dist/esm/slider/define.d.ts", + "types": "./dist/dts/slider/define.d.ts", "default": "./dist/esm/slider/define.js" }, "./spinner.js": { - "types": "./dist/esm/spinner/define.d.ts", + "types": "./dist/dts/spinner/define.d.ts", "default": "./dist/esm/spinner/define.js" }, "./switch.js": { - "types": "./dist/esm/switch/define.d.ts", + "types": "./dist/dts/switch/define.d.ts", "default": "./dist/esm/switch/define.js" }, "./tab.js": { - "types": "./dist/esm/tab/define.d.ts", + "types": "./dist/dts/tab/define.d.ts", "default": "./dist/esm/tab/define.js" }, "./tabs.js": { - "types": "./dist/esm/tabs/define.d.ts", + "types": "./dist/dts/tabs/define.d.ts", "default": "./dist/esm/tabs/define.js" }, "./tab-panel.js": { - "types": "./dist/esm/tab-panel/define.d.ts", + "types": "./dist/dts/tab-panel/define.d.ts", "default": "./dist/esm/tab-panel/define.js" }, "./text.js": { - "types": "./dist/esm/text/define.d.ts", + "types": "./dist/dts/text/define.d.ts", "default": "./dist/esm/text/define.js" }, "./text-input.js": { - "types": "./dist/esm/text-input/define.d.ts", + "types": "./dist/dts/text-input/define.d.ts", "default": "./dist/esm/text-input/define.js" }, "./toggle-button.js": { - "types": "./dist/esm/toggle-button/define.d.ts", + "types": "./dist/dts/toggle-button/define.d.ts", "default": "./dist/esm/toggle-button/define.js" }, "./theme.js": { - "types": "./dist/esm/theme/index.d.ts", + "types": "./dist/dts/theme/index.d.ts", "default": "./dist/esm/theme/index.js" } }, From ddf1b900aded134a8b48c7e9d21fce7e2571d4ed Mon Sep 17 00:00:00 2001 From: Ryan Merrill Date: Sat, 26 Aug 2023 00:16:47 -0400 Subject: [PATCH 159/203] Adds unit tests for CounterBadge (#28867) * Adds tests for counterBadge * Removes tests for slotted icon content * Adds tests to verify if showZero and dot are able to be set programmatically * Fixes linting errors * Changes beforeAll to beforeEach to fix flaky tests * Removes .only * Tries to unflake * Adds fixes for flaky tests * Updates tests without shadowContent query --- packages/web-components/.storybook/main.cjs | 2 +- .../src/counter-badge/counter-badge.spec.ts | 221 ++++++++++++++++++ 2 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 packages/web-components/src/counter-badge/counter-badge.spec.ts diff --git a/packages/web-components/.storybook/main.cjs b/packages/web-components/.storybook/main.cjs index 544ce1f0711a0..a6c4d1ab928b1 100644 --- a/packages/web-components/.storybook/main.cjs +++ b/packages/web-components/.storybook/main.cjs @@ -26,7 +26,7 @@ module.exports = /** @type {Omit { + let page: Page; + let element: Locator; + let root: Locator; + + test.beforeEach(async ({ browser }) => { + page = await browser.newPage(); + element = page.locator('fluent-counter-badge'); + root = page.locator('#root'); + await page.goto(fixtureURL('components-badge-counter-badge--counter-badge')); + }); + + test.afterEach(async () => { + await page.close(); + }); + + test('should handle overflow count property correctly', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(element).toHaveAttribute('overflow-count', '100'); + + await expect(element).toContainText('100+'); + }); + + test('should reflect the count attribute properly', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + await expect(element).toHaveAttribute('count', '5'); + + await expect(element).toContainText('5'); + }); + + test('should show 0 when showZero attribute is present and value is 0', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + await expect(element).toHaveAttribute('show-zero', ''); + await expect(element).toHaveJSProperty('showZero', true); + + await expect(element).toContainText('0'); + }); + + test('should show 0 when showZero is set programmatically', async () => { + await page.waitForSelector('fluent-counter-badge'); + await element.evaluate((node: CounterBadge) => { + node.showZero = true; + node.count = 0; + }); + await expect(element).toHaveJSProperty('showZero', true); + + await expect(element).toContainText('0'); + }); + + test('should render correctly with dot attribute', async () => { + await page.waitForSelector('fluent-counter-badge'); + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + await expect(element).toHaveJSProperty('dot', true); + + await expect(element).not.toContainText('5'); + }); + + test('should show dot programmatically', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await expect(element).toHaveJSProperty('dot', true); + await expect(element).not.toContainText('5'); + }); + + test('should hide dot programmatically', async () => { + await root.evaluate(node => { + node.innerHTML = /* html */ ` + + `; + }); + + await element.evaluate((node: CounterBadge) => { + node.dot = false; + }); + + await expect(element).toContainText('5'); + await expect(element).toHaveJSProperty('dot', false); + }); + + test('should reflect shape attribute and update property', async () => { + await element.evaluate((node: CounterBadge) => { + node.shape = 'circular'; + }); + await expect(element).toHaveAttribute('shape', 'circular'); + await expect(element).toHaveJSProperty('shape', 'circular'); + + await element.evaluate((node: CounterBadge) => { + node.shape = 'rounded'; + }); + await expect(element).toHaveAttribute('shape', 'rounded'); + await expect(element).toHaveJSProperty('shape', 'rounded'); + }); + + test('should reflect color attribute and update property', async () => { + await element.evaluate((node: CounterBadge) => { + node.color = 'brand'; + }); + await expect(element).toHaveAttribute('color', 'brand'); + await expect(element).toHaveJSProperty('color', 'brand'); + + await element.evaluate((node: CounterBadge) => { + node.color = 'danger'; + }); + await expect(element).toHaveAttribute('color', 'danger'); + await expect(element).toHaveJSProperty('color', 'danger'); + + await element.evaluate((node: CounterBadge) => { + node.color = 'important'; + }); + await expect(element).toHaveAttribute('color', 'important'); + await expect(element).toHaveJSProperty('color', 'important'); + + await element.evaluate((node: CounterBadge) => { + node.color = 'informative'; + }); + await expect(element).toHaveAttribute('color', 'informative'); + await expect(element).toHaveJSProperty('color', 'informative'); + + await element.evaluate((node: CounterBadge) => { + node.color = 'severe'; + }); + await expect(element).toHaveAttribute('color', 'severe'); + await expect(element).toHaveJSProperty('color', 'severe'); + + await element.evaluate((node: CounterBadge) => { + node.color = 'success'; + }); + await expect(element).toHaveAttribute('color', 'success'); + await expect(element).toHaveJSProperty('color', 'success'); + + await element.evaluate((node: CounterBadge) => { + node.color = 'subtle'; + }); + await expect(element).toHaveAttribute('color', 'subtle'); + await expect(element).toHaveJSProperty('color', 'subtle'); + + await element.evaluate((node: CounterBadge) => { + node.color = 'warning'; + }); + await expect(element).toHaveAttribute('color', 'warning'); + await expect(element).toHaveJSProperty('color', 'warning'); + }); + + test('should reflect size attribute and update property', async () => { + await element.evaluate((node: CounterBadge) => { + node.size = 'tiny'; + }); + await expect(element).toHaveAttribute('size', 'tiny'); + await expect(element).toHaveJSProperty('size', 'tiny'); + + await element.evaluate((node: CounterBadge) => { + node.size = 'extra-small'; + }); + await expect(element).toHaveAttribute('size', 'extra-small'); + await expect(element).toHaveJSProperty('size', 'extra-small'); + + await element.evaluate((node: CounterBadge) => { + node.size = 'small'; + }); + await expect(element).toHaveAttribute('size', 'small'); + await expect(element).toHaveJSProperty('size', 'small'); + + await element.evaluate((node: CounterBadge) => { + node.size = 'medium'; + }); + await expect(element).toHaveAttribute('size', 'medium'); + await expect(element).toHaveJSProperty('size', 'medium'); + + await element.evaluate((node: CounterBadge) => { + node.size = 'large'; + }); + await expect(element).toHaveAttribute('size', 'large'); + await expect(element).toHaveJSProperty('size', 'large'); + + await element.evaluate((node: CounterBadge) => { + node.size = 'extra-large'; + }); + await expect(element).toHaveAttribute('size', 'extra-large'); + await expect(element).toHaveJSProperty('size', 'extra-large'); + }); + + test('should reflect appearance attribute and update property', async () => { + await element.evaluate((node: CounterBadge) => { + node.appearance = 'filled'; + }); + await expect(element).toHaveAttribute('appearance', 'filled'); + await expect(element).toHaveJSProperty('appearance', 'filled'); + + await element.evaluate((node: CounterBadge) => { + node.appearance = 'ghost'; + }); + await expect(element).toHaveAttribute('appearance', 'ghost'); + await expect(element).toHaveJSProperty('appearance', 'ghost'); + }); +}); From f17dbf3ba00f88d6e1c9ca06e5c179ff28cd492d Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Mon, 28 Aug 2023 04:19:07 +0000 Subject: [PATCH 160/203] applying package updates --- apps/vr-tests-web-components/package.json | 2 +- ...ents-663811d0-6bde-44e5-8dc2-9857aea867db.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 5 files changed, 27 insertions(+), 10 deletions(-) delete mode 100644 change/@fluentui-web-components-663811d0-6bde-44e5-8dc2-9857aea867db.json diff --git a/apps/vr-tests-web-components/package.json b/apps/vr-tests-web-components/package.json index a71d93d9f2e63..f4c25c27c1b2c 100644 --- a/apps/vr-tests-web-components/package.json +++ b/apps/vr-tests-web-components/package.json @@ -23,7 +23,7 @@ "dependencies": { "@fluentui/react-button": "^9.2.3", "@fluentui/react-storybook-addon": "*", - "@fluentui/web-components": "3.0.0-beta.1", + "@fluentui/web-components": "3.0.0-beta.2", "tslib": "^2.1.0" } } diff --git a/change/@fluentui-web-components-663811d0-6bde-44e5-8dc2-9857aea867db.json b/change/@fluentui-web-components-663811d0-6bde-44e5-8dc2-9857aea867db.json deleted file mode 100644 index 785edb865d4d2..0000000000000 --- a/change/@fluentui-web-components-663811d0-6bde-44e5-8dc2-9857aea867db.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "Fixed pathing to types for package exports", - "packageName": "@fluentui/web-components", - "email": "mmansour@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 6e784210ce751..51d1d099d20cb 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Mon, 28 Aug 2023 04:19:02 GMT", + "tag": "@fluentui/web-components_v3.0.0-beta.2", + "version": "3.0.0-beta.2", + "comments": { + "prerelease": [ + { + "author": "mmansour@microsoft.com", + "package": "@fluentui/web-components", + "commit": "9d4c07c582596b55ceea4b68677fd74dd9236ae7", + "comment": "Fixed pathing to types for package exports" + } + ] + } + }, { "date": "Fri, 25 Aug 2023 04:19:39 GMT", "tag": "@fluentui/web-components_v3.0.0-beta.1", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index 6ad0eeaf459e0..a059857d9ce3a 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Fri, 25 Aug 2023 04:19:39 GMT and should not be manually modified. +This log was last generated on Mon, 28 Aug 2023 04:19:02 GMT and should not be manually modified. +## [3.0.0-beta.2](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-beta.2) + +Mon, 28 Aug 2023 04:19:02 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-beta.1..@fluentui/web-components_v3.0.0-beta.2) + +### Changes + +- Fixed pathing to types for package exports ([PR #28986](https://github.com/microsoft/fluentui/pull/28986) by mmansour@microsoft.com) + ## [3.0.0-beta.1](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-beta.1) Fri, 25 Aug 2023 04:19:39 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index bb3bbecc535f9..6bc78943ce61b 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -1,7 +1,7 @@ { "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", - "version": "3.0.0-beta.1", + "version": "3.0.0-beta.2", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 77c2d7106482a342f4c70b2334bf347e4a4ff854 Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Thu, 21 Sep 2023 10:59:26 -0700 Subject: [PATCH 161/203] accordion storybook content fix (#28729) * radio init * styles radio * reverts branch * input spec init * cleans up spec * formatting * updates component name to text input * updates component name in spec * accordion sb fixes: updates content * removes dead file --- packages/web-components/src/accordion/accordion.stories.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web-components/src/accordion/accordion.stories.ts b/packages/web-components/src/accordion/accordion.stories.ts index 967c20fb50d2d..5cd8e4a838d1d 100644 --- a/packages/web-components/src/accordion/accordion.stories.ts +++ b/packages/web-components/src/accordion/accordion.stories.ts @@ -69,7 +69,7 @@ const storyTemplate = html` block=${x => x.block} ?disabled=${x => x.disabled} > - Accordion Header 1 + Accordion Header 2 Accordion Panel 2 ` block=${x => x.block} ?disabled=${x => x.disabled} > - Accordion Header 1 + Accordion Header 3 Accordion Panel 3 From 4a8c229da390b55968d396ec73a43c5547b4326e Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Wed, 27 Sep 2023 11:57:55 -0700 Subject: [PATCH 162/203] Menu Web Component [ PRIORITY 1 ] (#27906) * radio init * styles radio * reverts branch * input spec init * cleans up spec * formatting * updates component name to text input * updates component name in spec * menu: menu init * menu: updates README * menu: updates template, styles * menu: updates menu and stories * menu: removes dead code * menu: removes folder and file * yarn change * menu: removes tab index on template slot * menu changes based on feedback * menu: updates stories * menu, emits event on expanded change * menu: updatews attr/property name to align with fluent ( expand --> open ) * menu: cleans up code * reverts dead file * menu: removes block styling * enhances cleanup of autoUpdate, conditionally remove mouseover event listener * Add defaultPrevented check to handleTriggerKeydown function * menu: adds open/close features * menu: fixes spelling error in readme * menu: adds part selector to positioningRegion * menu: adds z-index css variable, updates docs accordingly * menu: adds attr changed callback for closeOnScroll to manage event listeners * menu: adds exports --- ...-efa30982-7506-4a0d-80e5-e9ca22911289.json | 7 + packages/web-components/package.json | 4 + packages/web-components/src/index.ts | 1 + packages/web-components/src/menu/README.md | 145 ++++++ packages/web-components/src/menu/define.ts | 4 + packages/web-components/src/menu/index.ts | 4 + .../src/menu/menu.definition.ts | 17 + .../web-components/src/menu/menu.stories.ts | 106 +++++ .../web-components/src/menu/menu.styles.ts | 18 + .../web-components/src/menu/menu.template.ts | 26 ++ packages/web-components/src/menu/menu.ts | 426 ++++++++++++++++++ 11 files changed, 758 insertions(+) create mode 100644 change/@fluentui-web-components-efa30982-7506-4a0d-80e5-e9ca22911289.json create mode 100644 packages/web-components/src/menu/README.md create mode 100644 packages/web-components/src/menu/define.ts create mode 100644 packages/web-components/src/menu/index.ts create mode 100644 packages/web-components/src/menu/menu.definition.ts create mode 100644 packages/web-components/src/menu/menu.stories.ts create mode 100644 packages/web-components/src/menu/menu.styles.ts create mode 100644 packages/web-components/src/menu/menu.template.ts create mode 100644 packages/web-components/src/menu/menu.ts diff --git a/change/@fluentui-web-components-efa30982-7506-4a0d-80e5-e9ca22911289.json b/change/@fluentui-web-components-efa30982-7506-4a0d-80e5-e9ca22911289.json new file mode 100644 index 0000000000000..6e9794accd6a8 --- /dev/null +++ b/change/@fluentui-web-components-efa30982-7506-4a0d-80e5-e9ca22911289.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat(menu): adds menu web component", + "packageName": "@fluentui/web-components", + "email": "brian.christopher.brady@gmail.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 6bc78943ce61b..0979d6b63f2a6 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -71,6 +71,10 @@ "types": "./dist/dts/label/define.d.ts", "default": "./dist/esm/label/define.js" }, + "./menu.js": { + "types": "./dist/dts/menu/define.d.ts", + "default": "./dist/esm/menu/define.js" + }, "./menu-list.js": { "types": "./dist/dts/menu-list/define.d.ts", "default": "./dist/esm/menu-list/define.js" diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index 45128fb17a522..92750616f0785 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -10,6 +10,7 @@ export * from './counter-badge/index.js'; export * from './divider/index.js'; export * from './image/index.js'; export * from './label/index.js'; +export * from './menu/index.js'; export * from './menu-button/index.js'; export * from './menu-item/index.js'; export * from './menu-list/index.js'; diff --git a/packages/web-components/src/menu/README.md b/packages/web-components/src/menu/README.md new file mode 100644 index 0000000000000..4aeb719e66ca0 --- /dev/null +++ b/packages/web-components/src/menu/README.md @@ -0,0 +1,145 @@ +# Menu + +> A Menu component for handling menus and menu items in a user interface. + +
+ +## **Design Spec** + +There is no design spec for the `Menu` component as the `Menu` has no visual styles. The design spec for the `MenuList` can be found at [Fluent MenuList Spec](https://www.figma.com/file/jFWrkFq61GDdOhPlsz6AtX/Menu?type=design&node-id=2-39&mode=design&t=RQguhK8xTpmR2MFe-0) + +
+ +## **Engineering Spec** + +
+ +The Menu component is responsible for managing menus and their associated menu items. It handles the open/close functionality, focus management, and positioning strategy for showing the menu items. + +
+ +### Use Case + +Creating a menu component that can be used to display a list of options or actions. + +
+ +## Class: `Menu` + +
+ +### **Variables** + +
+ +### **Fields** + +| Name | Privacy | Type | Default | Description | +| -------------------- | ------- | --------------- | ------- | -------------------------------------------------------------------------------------- | +| `menu` | public | `HTMLElement[]` | | The menu element(s) to be displayed | +| `trigger` | public | `HTMLElement[]` | | The trigger element(s) for opening/closing menu | +| `open` | public | `boolean` | `false` | Specifies if the menu is open or closed | +| `menuContainer` | public | `HTMLElement` | | The container element for the menu items | +| `openOnHover` | public | `boolean` | `false` | Sets whether the menu opens on hover of menu trigger | +| `openOnContext` | public | `boolean` | `false` | Opens the menu on right click (context menu), removes all other menu open interactions | +| `closeOnScroll` | public | `boolean` | `false` | Close when scroll outside of it | +| `persistOnItemClick` | public | `boolean` | `false` | Determines if the menu open state should persis on click of menu item | + +
+ +### **Methods** + +| Name | Privacy | Description | Parameters | Return | +| --------------------------- | --------- | ------------------------------------------------------------------------------------------ | -------------------------------------- | ------ | +| `setComponent` | public | ets the trigger and menu list elements and adds event listeners. | | void | +| `setPositioning` | protected | Calculates and applies the positioning of the menu list based on available viewport space. | | void | +| `toggleMenu` | public | Toggles the open state of the menu. | | void | +| `closeMenu` | public | Closes the menu. | | void | +| `openMenu` | public | Opens the menu. | `e?: Event` | void | +| `focusMenuList` | public | Focuses on the menu list. | | void | +| `focusTrigger` | public | Focuses on the menu trigger. | | void | +| `openChanged` | public | Called whenever the open state changes. Emits `onOpenChange` event. | `newValue: boolean, oldValue: boolean` | void | +| `openOnHoverChanged` | public | Called whenever the 'openOnHover' property changes. | `newValue: boolean, oldValue: boolean` | void | +| `persistOnItemClickChanged` | public | Called whenever the 'persisitOnItem' property changes. | `newValue: boolean, oldValue: boolean` | void | +| `openOnContextChanged` | public | Called whenever the 'openOnContext' property changes. | `newValue: boolean, oldValue: boolean` | void | +| `handleMenuKeydown` | public | Handles keyboard interaction for the menu. | `e: KeyboardEvent` | void | +| `handleTriggerKeydown` | public | Handles keyboard interaction for the menu trigger. | `e: KeyboardEvent` | void | + +
+ +### **Events** + +| Name | Type | Description | +| -------------- | ---- | ----------------------------------------------------------- | +| `onOpenChange` | | emits custom `onOpenChange` event when opened state changes | + +
+ +### **Attributes** + +| Name | Field | +| ----------------------- | ------------------ | +| `open` | open | +| `open-on-hover` | openOnHover | +| `open-on-context` | openOnContext | +| `close-on-scroll` | closeOnScroll | +| `persist-on-item-click` | persistOnItemClick | + +
+ +### **Slots** + +| Name | Description | +| --------- | -------------------------------- | +| `trigger` | The trigger element for the menu | +| | The menulist element | + +
+ +### **CSS Variables** + +| Name | Description | +| -------------- | ------------------------------- | +| `z-index-menu` | Used to set z-index of the Menu | + +
+ +### **Template** + +```html + + + + +``` + +## **Accessibility** + +**WAI-ARIA Roles, States, and Properties** +
+ +- aria-haspopup +- aria-expanded + +
+ +## **Preparation** + +### **Fluent Web Component v3 v.s Fluent React 9** + +
+ +**Component and Slot Mapping** + +| Fluent UI React 9 | Fluent Web Components 3 | +| ----------------- | ----------------------- | +| `` | `` | +| `` | `` | +| `` | `` | + +
+ +| Fluent UI React 9 | Fluent Web Components | Description of difference | +| ----------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `hasIcons` | | React implementation requires user to pass the `hasIcons` to align menu items with icons. The web components implementation aligns content by default. | +| `hasCheckmarks` | | React implementation requires user to pass the `hasCheckmarks` to align menu items with checkmarks. The web components implementation aligns content by default. | diff --git a/packages/web-components/src/menu/define.ts b/packages/web-components/src/menu/define.ts new file mode 100644 index 0000000000000..950b97d9e6301 --- /dev/null +++ b/packages/web-components/src/menu/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './menu.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/menu/index.ts b/packages/web-components/src/menu/index.ts new file mode 100644 index 0000000000000..ed356e7171a09 --- /dev/null +++ b/packages/web-components/src/menu/index.ts @@ -0,0 +1,4 @@ +export * from './menu.js'; +export { template as MenuTemplate } from './menu.template.js'; +export { styles as MenuStyles } from './menu.styles.js'; +export { definition as MenuDefinition } from './menu.definition.js'; diff --git a/packages/web-components/src/menu/menu.definition.ts b/packages/web-components/src/menu/menu.definition.ts new file mode 100644 index 0000000000000..763260e744b9c --- /dev/null +++ b/packages/web-components/src/menu/menu.definition.ts @@ -0,0 +1,17 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Menu } from './menu.js'; +import { styles } from './menu.styles.js'; +import { template } from './menu.template.js'; + +/** + * The Fluent Menu Element. + * + * @public + * @remarks + * HTML Element: + */ +export const definition = Menu.compose({ + name: `${FluentDesignSystem.prefix}-menu`, + template, + styles, +}); diff --git a/packages/web-components/src/menu/menu.stories.ts b/packages/web-components/src/menu/menu.stories.ts new file mode 100644 index 0000000000000..f8114128d5554 --- /dev/null +++ b/packages/web-components/src/menu/menu.stories.ts @@ -0,0 +1,106 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../helpers.stories.js'; +import type { Menu as FluentMenu } from './menu.js'; +import './define.js'; + +type MenuStoryArgs = Args & FluentMenu; +type MenuStoryMeta = Meta; + +const storyTemplate = html` + + + Toggle Menu + + Menu item 1 + Menu item 2 + Menu item 3 + Menu item 4 + + +`; + +export default { + title: 'Components/Menu', + args: { + openOnHover: false, + openOnContext: false, + closeOnScroll: false, + persistOnItemClick: false, + }, + argTypes: { + openOnHover: { + description: 'Sets whether menu opens on hover', + table: { + defaultValue: { summary: false }, + }, + control: 'boolean', + defaultValue: false, + }, + openOnContext: { + description: 'Opens the menu on right click (context menu), removes all other menu open interactions', + table: { + defaultValue: { summary: false }, + }, + control: 'boolean', + defaultValue: false, + }, + closeOnScroll: { + description: 'Close when scroll outside of it', + table: { + defaultValue: { summary: false }, + }, + control: 'boolean', + defaultValue: false, + }, + persistOnItemClick: { + description: 'Prevents the menu from closing when an item is clicked', + table: { + defaultValue: { summary: false }, + }, + control: 'boolean', + defaultValue: false, + }, + }, +} as MenuStoryMeta; + +export const Menu = renderComponent(storyTemplate).bind({}); + +export const MenuOpenOnHover = renderComponent(html` +
+ + Toggle Menu + + Menu item 1 + Menu item 2 + Menu item 3 + Menu item 4 + + +
+`); + +export const MenuOpenOnContext = renderComponent(html` +
+ + Toggle Menu + + Menu item 1 + Menu item 2 + Menu item 3 + Menu item 4 + + +
+`); diff --git a/packages/web-components/src/menu/menu.styles.ts b/packages/web-components/src/menu/menu.styles.ts new file mode 100644 index 0000000000000..a67901f6168bf --- /dev/null +++ b/packages/web-components/src/menu/menu.styles.ts @@ -0,0 +1,18 @@ +import { css } from '@microsoft/fast-element'; +import {} from '../theme/design-tokens.js'; + +/** Menu styles + * @public + */ +export const styles = css` + :host { + position: relative; + z-index: var(--z-index-menu, 1); + } + .positioning-container { + position: fixed; + top: 0; + left: 0; + transform: translate(0, 0); + } +`; diff --git a/packages/web-components/src/menu/menu.template.ts b/packages/web-components/src/menu/menu.template.ts new file mode 100644 index 0000000000000..6609d3eef7e14 --- /dev/null +++ b/packages/web-components/src/menu/menu.template.ts @@ -0,0 +1,26 @@ +import { elements, ElementViewTemplate, html, ref, slotted } from '@microsoft/fast-element'; +import type { Menu } from './menu.js'; + +export function menuTemplate(): ElementViewTemplate { + return html` + + `; +} + +export const template: ElementViewTemplate = menuTemplate(); diff --git a/packages/web-components/src/menu/menu.ts b/packages/web-components/src/menu/menu.ts new file mode 100644 index 0000000000000..c79d7c777bed2 --- /dev/null +++ b/packages/web-components/src/menu/menu.ts @@ -0,0 +1,426 @@ +import { attr, FASTElement, observable, Updates } from '@microsoft/fast-element'; +import { autoUpdate, computePosition, flip, hide, size } from '@floating-ui/dom'; +import { keyEnter, keyEscape, keySpace, keyTab } from '@microsoft/fast-web-utilities'; +import { MenuList } from '../menu-list/menu-list.js'; + +/** + * The Menu class represents a menu component. + * @public + */ +export class Menu extends FASTElement { + /** + * Determines if the menu should open on hover. + * @public + */ + @observable + @attr({ attribute: 'open-on-hover', mode: 'boolean' }) + public openOnHover?: boolean = false; + + /** + * Determines if the menu should open on right click. + * @public + */ + @observable + @attr({ attribute: 'open-on-context', mode: 'boolean' }) + public openOnContext?: boolean = false; + + /** + * Determines if the menu should close on scroll. + * @public + */ + @observable + @attr({ attribute: 'close-on-scroll', mode: 'boolean' }) + public closeOnScroll?: boolean = false; + + /** + * Determines if the menu open state should persis on click of menu item + * @public + */ + @observable + @attr({ attribute: 'persist-on-item-click', mode: 'boolean' }) + public persistOnItemClick?: boolean = false; + + /** + * Defines whether the menu is open or not. + * @public + */ + @observable + @attr({ mode: 'boolean' }) + public open: boolean = false; + + /** + * Holds the slotted menu list. + * @public + */ + @observable + public slottedMenuList: MenuList[] = []; + + /** + * Holds the slotted triggers. + * @public + */ + @observable + public slottedTriggers: HTMLElement[] = []; + + /** + * The positioning container of the menu. + * @internal + */ + public positioningContainer?: HTMLElement; + + /** + * The trigger element of the menu. + * @private + */ + private _trigger?: HTMLElement; + + /** + * The menu list element of the menu. + * @private + */ + private _menuList?: HTMLElement; + + /** + * Holds a reference to a function that is used to cleanup resources. + * @public + */ + public cleanup?: () => void; + + /** + * Called when the element is connected to the DOM. + * Sets up the component. + * @public + */ + public connectedCallback() { + super.connectedCallback(); + Updates.enqueue(() => this.setComponent()); + } + + /** + * Called when the element is disconnected from the DOM. + * Removes event listeners. + * @public + */ + public disconnectedCallback() { + super.disconnectedCallback(); + this.cleanup?.(); + this.removeListeners(); + } + + /** + * Sets the component. + * Sets the trigger and menu list elements and adds event listeners. + * @public + */ + public setComponent(): void { + if (this.$fastController.isConnected && this.slottedMenuList.length && this.slottedTriggers.length) { + this._trigger = this.slottedTriggers![0]; + this._menuList = this.slottedMenuList![0]; + this._trigger.setAttribute('aria-haspopup', 'true'); + this._trigger.setAttribute('aria-expanded', `${this.open}`); + this.addListeners(); + } + } + + /** + * Toggles the open state of the menu. + * @public + */ + public toggleMenu = () => { + if (this.open) { + this.closeMenu(); + } else { + this.openMenu(); + } + }; + + /** + * Closes the menu. + * @public + */ + public closeMenu = () => { + this.open = false; + if (this.closeOnScroll) { + document.removeEventListener('scroll', this.closeMenu); + } + }; + + /** + * Opens the menu. + * @public + */ + public openMenu = (e?: Event) => { + this.open = true; + if (e && this.openOnContext) { + e.preventDefault(); + } + if (this.closeOnScroll) { + document.addEventListener('scroll', this.closeMenu); + } + }; + + /** + * Focuses on the menu list. + * @public + */ + public focusMenuList(): void { + if (this.open && this._menuList) { + Updates.enqueue(() => { + this._menuList!.focus(); + }); + } + } + + /** + * Focuses on the menu trigger. + * @public + */ + public focusTrigger(): void { + if (!this.open && this._trigger) { + Updates.enqueue(() => { + this._trigger!.focus(); + }); + } + } + + /** + * Called whenever the open state changes. + * Updates the 'aria-expanded' attribute and sets the positioning of the menu. + * Sets menu list position + * emits openChanged event + * @public + * @param {boolean} oldValue - The previous value of 'open'. + * @param {boolean} newValue - The new value of 'open'. + */ + public openChanged(oldValue: boolean, newValue: boolean): void { + if (this.$fastController.isConnected && this._trigger instanceof HTMLElement) { + this._trigger.setAttribute('aria-expanded', `${this.open}`); + if (this._menuList && this.open) { + Updates.enqueue(this.setPositioningTask); + } + } + this.cleanup?.(); + this.$emit('onOpenChange', { open: newValue }); + } + + /** + * Called whenever the 'openOnHover' property changes. + * Adds or removes a 'mouseover' event listener to the trigger based on the new value. + * @public + * @param {boolean} oldValue - The previous value of 'openOnHover'. + * @param {boolean} newValue - The new value of 'openOnHover'. + */ + public openOnHoverChanged(oldValue: boolean, newValue: boolean): void { + if (newValue) { + this._trigger?.addEventListener('mouseover', this.openMenu); + } else { + this._trigger?.removeEventListener('mouseover', this.openMenu); + } + } + + /** + * Called whenever the 'persistOnItemClick' property changes. + * Adds or removes a 'click' event listener to the menu list based on the new value. + * @public + * @param {boolean} oldValue - The previous value of 'persistOnItemClick'. + * @param {boolean} newValue - The new value of 'persistOnItemClick'. + */ + public persistOnItemClickChanged(oldValue: boolean, newValue: boolean): void { + if (!newValue) { + this._menuList?.addEventListener('click', this.closeMenu); + } else { + this._menuList?.removeEventListener('click', this.closeMenu); + } + } + + /** + * Called whenever the 'openOnContext' property changes. + * Adds or removes a 'contextmenu' event listener to the trigger based on the new value. + * @public + * @param {boolean} oldValue - The previous value of 'openOnContext'. + * @param {boolean} newValue - The new value of 'openOnContext'. + */ + public openOnContextChanged(oldValue: boolean, newValue: boolean): void { + if (newValue) { + this._trigger?.addEventListener('contextmenu', this.openMenu); + } else { + this._trigger?.removeEventListener('contextmenu', this.openMenu); + } + } + + /** + * Called whenever the 'closeOnScroll' property changes. + * Adds or removes a 'closeOnScroll' event listener to the trigger based on the new value. + * @public + * @param {boolean} oldValue - The previous value of 'closeOnScroll'. + * @param {boolean} newValue - The new value of 'closeOnScroll'. + */ + public closeOnScrollChanged(oldValue: boolean, newValue: boolean): void { + if (newValue) { + document.addEventListener('scroll', this.closeMenu); + } else { + document.removeEventListener('scroll', this.closeMenu); + } + } + + /** + * The task to set the positioning of the menu. + * @protected + */ + protected setPositioningTask = () => { + this.setPositioning(); + }; + + /** + * Sets the positioning of the menu. + * @protected + */ + protected setPositioning(): void { + if (this.$fastController.isConnected && this._menuList && this.open && this._trigger) { + this.cleanup = autoUpdate(this, this.positioningContainer!, async () => { + const { middlewareData, x, y } = await computePosition(this._trigger!, this.positioningContainer!, { + placement: 'bottom', + strategy: 'fixed', + middleware: [ + flip(), + size({ + apply: ({ availableHeight, rects }) => { + this.positioningContainer?.style && + Object.assign(this.positioningContainer!.style, { + maxHeight: `${availableHeight}px`, + width: `${rects.reference.width}px`, + }); + }, + }), + hide(), + ], + }); + if (middlewareData.hide?.referenceHidden) { + this.open = false; + return; + } + + this.positioningContainer?.style && + Object.assign(this.positioningContainer.style, { + position: 'fixed', + top: '0', + left: '0', + transform: `translate(${x}px, ${y}px)`, + }); + }); + } + } + + /** + * Adds event listeners. + * Adds click and keydown event listeners to the trigger and a click event listener to the document. + * If 'openOnHover' is true, adds a 'mouseover' event listener to the trigger. + * @public + */ + private addListeners(): void { + document.addEventListener('click', this.handleDocumentClick); + this._trigger?.addEventListener('keydown', this.handleTriggerKeydown); + if (!this.persistOnItemClick) { + this._menuList?.addEventListener('click', this.closeMenu); + } + if (this.openOnHover) { + this._trigger?.addEventListener('mouseover', this.openMenu); + } else if (this.openOnContext) { + this._trigger?.addEventListener('contextmenu', this.openMenu); + } else { + this._trigger?.addEventListener('click', this.toggleMenu); + } + } + + /** + * Removes event listeners. + * Removes click and keydown event listeners from the trigger and a click event listener from the document. + * Also removes 'mouseover' event listeners from the trigger. + * @private + */ + private removeListeners(): void { + document.removeEventListener('click', this.handleDocumentClick); + this._trigger?.removeEventListener('keydown', this.handleTriggerKeydown); + if (!this.persistOnItemClick) { + this._menuList?.removeEventListener('click', this.closeMenu); + } + if (this.openOnHover) { + this._trigger?.removeEventListener('mouseover', this.openMenu); + } + if (this.openOnContext) { + this._trigger?.removeEventListener('contextmenu', this.openMenu); + } else { + this._trigger?.removeEventListener('click', this.toggleMenu); + } + } + + /** + * Handles keyboard interaction for the menu. + * Closes the menu and focuses on the trigger when the Escape key is pressed. + * Closes the menu when the Tab key is pressed. + * @public + * @param {KeyboardEvent} e - the keyboard event + */ + public handleMenuKeydown(e: KeyboardEvent): boolean | void { + if (e.defaultPrevented) { + return; + } + const key = e.key; + + switch (key) { + case keyEscape: + e.preventDefault(); + if (this.open) { + this.closeMenu(); + this.focusTrigger(); + } + break; + case keyTab: + if (this.open) { + this.closeMenu(); + } + if (e.shiftKey) { + this.focusTrigger(); + } + default: + return true; + } + } + + /** + * Handles keyboard interaction for the trigger. + * Toggles the menu when the Space or Enter key is pressed. + * If the menu is open, focuses on the menu list. + * @public + * @param {KeyboardEvent} e - the keyboard event + */ + public handleTriggerKeydown = (e: KeyboardEvent): boolean | void => { + if (e.defaultPrevented) { + return; + } + const key = e.key; + switch (key) { + case keySpace: + case keyEnter: + e.preventDefault(); + this.toggleMenu(); + if (this.open) { + this.focusMenuList(); + } + break; + default: + return true; + } + }; + + /** + * Handles document click events to close the menu when a click occurs outside of the menu or the trigger. + * @private + * @param {Event} e - The event triggered on document click. + */ + private handleDocumentClick = (e: any) => { + if (e && !e.composedPath().includes(this._menuList) && !e.composedPath().includes(this._trigger)) { + this.closeMenu(); + } + }; +} From 20d2355116ffef8f942b560fbb61a489b29f714a Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Thu, 28 Sep 2023 04:18:54 +0000 Subject: [PATCH 163/203] applying package updates --- apps/vr-tests-web-components/package.json | 2 +- ...ents-efa30982-7506-4a0d-80e5-e9ca22911289.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 5 files changed, 27 insertions(+), 10 deletions(-) delete mode 100644 change/@fluentui-web-components-efa30982-7506-4a0d-80e5-e9ca22911289.json diff --git a/apps/vr-tests-web-components/package.json b/apps/vr-tests-web-components/package.json index f4c25c27c1b2c..863055e974c63 100644 --- a/apps/vr-tests-web-components/package.json +++ b/apps/vr-tests-web-components/package.json @@ -23,7 +23,7 @@ "dependencies": { "@fluentui/react-button": "^9.2.3", "@fluentui/react-storybook-addon": "*", - "@fluentui/web-components": "3.0.0-beta.2", + "@fluentui/web-components": "3.0.0-beta.3", "tslib": "^2.1.0" } } diff --git a/change/@fluentui-web-components-efa30982-7506-4a0d-80e5-e9ca22911289.json b/change/@fluentui-web-components-efa30982-7506-4a0d-80e5-e9ca22911289.json deleted file mode 100644 index 6e9794accd6a8..0000000000000 --- a/change/@fluentui-web-components-efa30982-7506-4a0d-80e5-e9ca22911289.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat(menu): adds menu web component", - "packageName": "@fluentui/web-components", - "email": "brian.christopher.brady@gmail.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 51d1d099d20cb..3a36364615057 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Thu, 28 Sep 2023 04:18:49 GMT", + "tag": "@fluentui/web-components_v3.0.0-beta.3", + "version": "3.0.0-beta.3", + "comments": { + "prerelease": [ + { + "author": "brian.christopher.brady@gmail.com", + "package": "@fluentui/web-components", + "commit": "980b0d394322fd6a11ea85d57721e928ca4803a5", + "comment": "feat(menu): adds menu web component" + } + ] + } + }, { "date": "Mon, 28 Aug 2023 04:19:02 GMT", "tag": "@fluentui/web-components_v3.0.0-beta.2", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index a059857d9ce3a..e966b66ebf5eb 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Mon, 28 Aug 2023 04:19:02 GMT and should not be manually modified. +This log was last generated on Thu, 28 Sep 2023 04:18:49 GMT and should not be manually modified. +## [3.0.0-beta.3](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-beta.3) + +Thu, 28 Sep 2023 04:18:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-beta.2..@fluentui/web-components_v3.0.0-beta.3) + +### Changes + +- feat(menu): adds menu web component ([PR #27906](https://github.com/microsoft/fluentui/pull/27906) by brian.christopher.brady@gmail.com) + ## [3.0.0-beta.2](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-beta.2) Mon, 28 Aug 2023 04:19:02 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 0979d6b63f2a6..6017b0f8ca42e 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -1,7 +1,7 @@ { "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", - "version": "3.0.0-beta.2", + "version": "3.0.0-beta.3", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 42021e5aad4e74ff7c7c6d517ac1d5493e05dfeb Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Thu, 12 Oct 2023 10:40:42 -0700 Subject: [PATCH 164/203] fix(web-components): update switch to use margin for checked state to support RTL (#29505) * use margin for switch checked transition to support RTL * change files --- ...eb-components-f70c1f20-47e3-4e76-9cb0-53fef171209f.json | 7 +++++++ packages/web-components/src/switch/switch.styles.ts | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 change/@fluentui-web-components-f70c1f20-47e3-4e76-9cb0-53fef171209f.json diff --git a/change/@fluentui-web-components-f70c1f20-47e3-4e76-9cb0-53fef171209f.json b/change/@fluentui-web-components-f70c1f20-47e3-4e76-9cb0-53fef171209f.json new file mode 100644 index 0000000000000..fe0cfd8913670 --- /dev/null +++ b/change/@fluentui-web-components-f70c1f20-47e3-4e76-9cb0-53fef171209f.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "fix: update switch to use margin instead of transform for the checked state to support RTL", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/src/switch/switch.styles.ts b/packages/web-components/src/switch/switch.styles.ts index 81aa986c93ca5..bb0f14dc84a4f 100644 --- a/packages/web-components/src/switch/switch.styles.ts +++ b/packages/web-components/src/switch/switch.styles.ts @@ -118,14 +118,15 @@ export const styles = css` height: 14px; width: 14px; border-radius: 50%; + margin-inline-start: 0; background-color: ${colorNeutralForeground3}; transition-duration: ${durationNormal}; transition-timing-function: ${curveEasyEase}; - transition-property: transform; + transition-property: margin-inline-start; } :host([aria-checked='true']) .checked-indicator { background-color: ${colorNeutralForegroundInverted}; - transform: translateX(20px); + margin-inline-start: calc(100% - 14px); } :host([aria-checked='true']:hover) .checked-indicator { background: ${colorNeutralForegroundInvertedHover}; From cb9e133ce60c8f21f0a9a29f6b11e553dbfeac2c Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Fri, 13 Oct 2023 04:17:32 +0000 Subject: [PATCH 165/203] applying package updates --- apps/vr-tests-web-components/package.json | 2 +- ...ents-f70c1f20-47e3-4e76-9cb0-53fef171209f.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 5 files changed, 27 insertions(+), 10 deletions(-) delete mode 100644 change/@fluentui-web-components-f70c1f20-47e3-4e76-9cb0-53fef171209f.json diff --git a/apps/vr-tests-web-components/package.json b/apps/vr-tests-web-components/package.json index 863055e974c63..634058ff0a81f 100644 --- a/apps/vr-tests-web-components/package.json +++ b/apps/vr-tests-web-components/package.json @@ -23,7 +23,7 @@ "dependencies": { "@fluentui/react-button": "^9.2.3", "@fluentui/react-storybook-addon": "*", - "@fluentui/web-components": "3.0.0-beta.3", + "@fluentui/web-components": "3.0.0-beta.4", "tslib": "^2.1.0" } } diff --git a/change/@fluentui-web-components-f70c1f20-47e3-4e76-9cb0-53fef171209f.json b/change/@fluentui-web-components-f70c1f20-47e3-4e76-9cb0-53fef171209f.json deleted file mode 100644 index fe0cfd8913670..0000000000000 --- a/change/@fluentui-web-components-f70c1f20-47e3-4e76-9cb0-53fef171209f.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "fix: update switch to use margin instead of transform for the checked state to support RTL", - "packageName": "@fluentui/web-components", - "email": "chhol@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 3a36364615057..0061f850f41d1 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Fri, 13 Oct 2023 04:17:27 GMT", + "tag": "@fluentui/web-components_v3.0.0-beta.4", + "version": "3.0.0-beta.4", + "comments": { + "prerelease": [ + { + "author": "chhol@microsoft.com", + "package": "@fluentui/web-components", + "commit": "af42938529ee2284a933a9f64db163c3bf283400", + "comment": "fix: update switch to use margin instead of transform for the checked state to support RTL" + } + ] + } + }, { "date": "Thu, 28 Sep 2023 04:18:49 GMT", "tag": "@fluentui/web-components_v3.0.0-beta.3", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index e966b66ebf5eb..081359c350194 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Thu, 28 Sep 2023 04:18:49 GMT and should not be manually modified. +This log was last generated on Fri, 13 Oct 2023 04:17:27 GMT and should not be manually modified. +## [3.0.0-beta.4](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-beta.4) + +Fri, 13 Oct 2023 04:17:27 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-beta.3..@fluentui/web-components_v3.0.0-beta.4) + +### Changes + +- fix: update switch to use margin instead of transform for the checked state to support RTL ([PR #29505](https://github.com/microsoft/fluentui/pull/29505) by chhol@microsoft.com) + ## [3.0.0-beta.3](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-beta.3) Thu, 28 Sep 2023 04:18:49 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 6017b0f8ca42e..475ee1209c309 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -1,7 +1,7 @@ { "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", - "version": "3.0.0-beta.3", + "version": "3.0.0-beta.4", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 530fc2c3227d3cda8af15597da0f0b792925b671 Mon Sep 17 00:00:00 2001 From: Hale Rankin Date: Wed, 18 Oct 2023 10:38:26 -0700 Subject: [PATCH 166/203] Adds Menu Component to sideEffects (#29581) * Adds menu component definition to list of sideEffects. * Generates change file. --------- Co-authored-by: Hale Rankin --- ...eb-components-eb7910d3-4886-4c46-a3d3-4cb448a176eb.json | 7 +++++++ packages/web-components/package.json | 1 + 2 files changed, 8 insertions(+) create mode 100644 change/@fluentui-web-components-eb7910d3-4886-4c46-a3d3-4cb448a176eb.json diff --git a/change/@fluentui-web-components-eb7910d3-4886-4c46-a3d3-4cb448a176eb.json b/change/@fluentui-web-components-eb7910d3-4886-4c46-a3d3-4cb448a176eb.json new file mode 100644 index 0000000000000..02e5247b795f3 --- /dev/null +++ b/change/@fluentui-web-components-eb7910d3-4886-4c46-a3d3-4cb448a176eb.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Updates package with Menu component sideEffect.", + "packageName": "@fluentui/web-components", + "email": "hale.rankin@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 475ee1209c309..1a7113c663c49 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -153,6 +153,7 @@ "./dist/esm/divider/define.js", "./dist/esm/image/define.js", "./dist/esm/label/define.js", + "./dist/esm/menu/define.js", "./dist/esm/menu-list/define.js", "./dist/esm/menu-button/define.js", "./dist/esm/menu-item/define.js", From cfd444a9df470c30d52dd68dd158061479bcfb3e Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Thu, 19 Oct 2023 04:18:11 +0000 Subject: [PATCH 167/203] applying package updates --- apps/vr-tests-web-components/package.json | 2 +- ...ents-eb7910d3-4886-4c46-a3d3-4cb448a176eb.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 5 files changed, 27 insertions(+), 10 deletions(-) delete mode 100644 change/@fluentui-web-components-eb7910d3-4886-4c46-a3d3-4cb448a176eb.json diff --git a/apps/vr-tests-web-components/package.json b/apps/vr-tests-web-components/package.json index 634058ff0a81f..ecbff995bffc1 100644 --- a/apps/vr-tests-web-components/package.json +++ b/apps/vr-tests-web-components/package.json @@ -23,7 +23,7 @@ "dependencies": { "@fluentui/react-button": "^9.2.3", "@fluentui/react-storybook-addon": "*", - "@fluentui/web-components": "3.0.0-beta.4", + "@fluentui/web-components": "3.0.0-beta.5", "tslib": "^2.1.0" } } diff --git a/change/@fluentui-web-components-eb7910d3-4886-4c46-a3d3-4cb448a176eb.json b/change/@fluentui-web-components-eb7910d3-4886-4c46-a3d3-4cb448a176eb.json deleted file mode 100644 index 02e5247b795f3..0000000000000 --- a/change/@fluentui-web-components-eb7910d3-4886-4c46-a3d3-4cb448a176eb.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "Updates package with Menu component sideEffect.", - "packageName": "@fluentui/web-components", - "email": "hale.rankin@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 0061f850f41d1..b26a12d71cae8 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Thu, 19 Oct 2023 04:18:07 GMT", + "tag": "@fluentui/web-components_v3.0.0-beta.5", + "version": "3.0.0-beta.5", + "comments": { + "prerelease": [ + { + "author": "hale.rankin@microsoft.com", + "package": "@fluentui/web-components", + "commit": "ef39b5c4329868b9426612c188e31496b26d75e5", + "comment": "Updates package with Menu component sideEffect." + } + ] + } + }, { "date": "Fri, 13 Oct 2023 04:17:27 GMT", "tag": "@fluentui/web-components_v3.0.0-beta.4", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index 081359c350194..ff2fe09bc138a 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Fri, 13 Oct 2023 04:17:27 GMT and should not be manually modified. +This log was last generated on Thu, 19 Oct 2023 04:18:07 GMT and should not be manually modified. +## [3.0.0-beta.5](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-beta.5) + +Thu, 19 Oct 2023 04:18:07 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-beta.4..@fluentui/web-components_v3.0.0-beta.5) + +### Changes + +- Updates package with Menu component sideEffect. ([PR #29581](https://github.com/microsoft/fluentui/pull/29581) by hale.rankin@microsoft.com) + ## [3.0.0-beta.4](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-beta.4) Fri, 13 Oct 2023 04:17:27 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 1a7113c663c49..f7d382b510e9c 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -1,7 +1,7 @@ { "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", - "version": "3.0.0-beta.4", + "version": "3.0.0-beta.5", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 8712d19dfacbab2f091ccfe90d1e97c5617c7c5b Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Wed, 25 Oct 2023 11:43:59 -0700 Subject: [PATCH 168/203] Web Component Dialog (#28569) * dialog init * dialog: updates stories, styles, and docs * dialog: updates styles * dialog: removes dead code, cleans up * dialog: updates styles * updates docs * deletes dead code * dialog: addresses PR feedback * reverts dead file * dialog: updates styles per feedback * drawer: updates template, styles * dialog: removes attr changed callback * dialog: updates slot names for react parity, updates docs * yarn change * dialog: addresses feedback * dialog: updates README * dialog: fixes responsive styles * dialog: removes dead styles * dialog: updates readme docs * dialog: reworks dialog to use navtive html dialog element * dialog: fixes jsdoc * dialog: updates slot names for closer parity with fv9, updates stories and docs * dialog: updates README * dialog: updates template class names * dialog: updates backdrop to use fluent token * dialog: adds two column layout story * dialog: adds additional stories * dialog: adds exports to index and package json * dialog: fixes style token imports * dialog: cleans up open state * dialog: updates template slot names * dialog: updates property name * dialog: removes change-focus * dialog: syncs open attr * dialog: sync open attribute * dialog: updates storybook docs * dialog: updates readme docs --- ...-c3eff1b3-5486-4127-9d4b-c9d6d05fdb24.json | 7 + packages/web-components/package.json | 5 + packages/web-components/src/dialog/README.md | 91 +++ packages/web-components/src/dialog/define.ts | 4 + .../src/dialog/dialog.definition.ts | 17 + .../src/dialog/dialog.options.ts | 13 + .../src/dialog/dialog.stories.ts | 636 ++++++++++++++++++ .../src/dialog/dialog.styles.ts | 121 ++++ .../src/dialog/dialog.template.ts | 67 ++ packages/web-components/src/dialog/dialog.ts | 400 +++++++++++ packages/web-components/src/dialog/index.ts | 4 + packages/web-components/src/index.ts | 1 + 12 files changed, 1366 insertions(+) create mode 100644 change/@fluentui-web-components-c3eff1b3-5486-4127-9d4b-c9d6d05fdb24.json create mode 100644 packages/web-components/src/dialog/README.md create mode 100644 packages/web-components/src/dialog/define.ts create mode 100644 packages/web-components/src/dialog/dialog.definition.ts create mode 100644 packages/web-components/src/dialog/dialog.options.ts create mode 100644 packages/web-components/src/dialog/dialog.stories.ts create mode 100644 packages/web-components/src/dialog/dialog.styles.ts create mode 100644 packages/web-components/src/dialog/dialog.template.ts create mode 100644 packages/web-components/src/dialog/dialog.ts create mode 100644 packages/web-components/src/dialog/index.ts diff --git a/change/@fluentui-web-components-c3eff1b3-5486-4127-9d4b-c9d6d05fdb24.json b/change/@fluentui-web-components-c3eff1b3-5486-4127-9d4b-c9d6d05fdb24.json new file mode 100644 index 0000000000000..f15f2159a265d --- /dev/null +++ b/change/@fluentui-web-components-c3eff1b3-5486-4127-9d4b-c9d6d05fdb24.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat(dialog): add dialog web component", + "packageName": "@fluentui/web-components", + "email": "brian.christopher.brady@gmail.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/package.json b/packages/web-components/package.json index f7d382b510e9c..2e09e55b8d680 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -59,6 +59,10 @@ "types": "./dist/dts/counter-badge/define.d.ts", "default": "./dist/esm/counter-badge/define.js" }, + "./dialog.js": { + "types": "./dist/dts/dialog/define.d.ts", + "default": "./dist/esm/dialog/define.js" + }, "./divider.js": { "types": "./dist/dts/divider/define.d.ts", "default": "./dist/esm/divider/define.js" @@ -150,6 +154,7 @@ "./dist/esm/checkbox/define.js", "./dist/esm/compound-button/define.js", "./dist/esm/counter-badge/define.js", + "./dist/esm/dialog/define.js", "./dist/esm/divider/define.js", "./dist/esm/image/define.js", "./dist/esm/label/define.js", diff --git a/packages/web-components/src/dialog/README.md b/packages/web-components/src/dialog/README.md new file mode 100644 index 0000000000000..df863504dd81f --- /dev/null +++ b/packages/web-components/src/dialog/README.md @@ -0,0 +1,91 @@ +# Dialog + +> Dialog is a window overlaid on either the primary window or another dialog window. Windows under a modal dialog are inert. That is, users cannot interact with content outside an active dialog window. Inert content outside an active dialog is typically visually obscured or dimmed so it is difficult to discern, and in some implementations, attempts to interact with the inert content cause the dialog to close. + +## **Design Spec** + +[Link to Dialog in Figma](https://www.figma.com/file/jtF47yOXDxkI00ZkydE999/Dialog?type=design&node-id=2605%3A15263&mode=dev) + +## **Engineering Spec** + +Fluent WC3 Dialog has feature parity with the Fluent UI React 9 Dialog implementation but not direct parity. + +## Superclass: [FASTElement](https://www.fast.design/docs/fast-element/defining-elements) + +## Class: `Dialog` + +
+ +### **Component Name** + +`` + +### **Basic Implemenation** + +```html + + + Dialog + + + Default Content + + + Do Something + Close + +``` + +### **Attributes** + +| Name | Privacy | Type | Default | Description | +| ------------------ | ------- | ----------------- | ----------------------- | --------------------------------------------------------- | +| `modal-type` | public | `DialogModalType` | `DialogModalType.modal` | Indicates that the type of modal to render. | +| `open` | public | `boolean` | `false` | Controls the open state of the dialog | +| `no-title-action` | public | `boolean` | `false` | Used to set whether the default title action is rendered. | +| `aria-labelledby` | public | `string` | `undefined` | optional based on implementation\*\* | +| `aria-describedby` | public | `string` | `undefined` | optional based on implementation\*\* | +| `aria-label ` | public | `string` | `undefined` | optional based on implementation\*\* | + +\*\* See the [W3C Specification](https://w3c.github.io/aria-practices/#dialog_roles_states_props) for requirements and details. + +
+ +### **Methods** + +| Name | Privacy | Description | Parameters | Return | Inherited From | +| ------ | ------- | ------------------------------ | ---------- | ------ | -------------- | +| `hide` | public | The method to hide the dialog. | | void | FASTDialog | +| `show` | public | The method to show the dialog. | | void | FASTDialog | + +
+ +### **Slots** + +| Name | Description | +| -------------- | ---------------------------------------------------------- | +| `title` | slot for title content | +| `title-action` | slot for close button | +| | default slot for content rendered between title and footer | +| `action` | slot for actions content | + +### **Events** + +| Name | Description | Details | +| -------------- | --------------------------------------------------------------- | -------------------------------------------------- | +| `onOpenChange` | Event fired when the component transitions from its open state. | `{ open: this.dialog.open, dismissed: dismissed }` | + +## **Preparation** + +### **Fluent Web Component v3 v.s Fluent React 9** + +**Component, Element, and Slot Mapping** + +| Fluent UI React 9 | Fluent Web Components 3 | Description of difference | +| ------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `` | `` | tag name | +| `` | methods: `hide() show()` | In the React version of our components, a "DialogTrigger" component is utilized as part of a composite component of Dialog. The DialogTrigger component provides functionality for toggling the visibility of the Dialog component.
In the Web Component version does not include a dialog trigger. Instead, it expects the user to directly access methods on the Dialog class or utilize CSS to control the visibility of the dialog component. | +| `` | `dialog::backdrop` | In the React version of our components, the DialogSurface component is used as part of the composite Dialog component to represent the dimmed background of the dialog.
The Web Component version utilizes the HTML dialog ::backdrop pseudoelement. | +| `` | `slot: title` | In the React version of our components, the component is used to implement the title of the dialog.
In the Web Component version, the title is provided through the title slot. | +| `` | `slot: title-action` | In the React version of our components, the component the DialogTitles action prop.
In the Web Component version, the title action is provided through the Dialogs title-action slot | +| `` | `slot: action` | In the React version of our components, the component is used to implement the actions within the dialog.
In the Web Component version, actions are passsed through the `action` slot | diff --git a/packages/web-components/src/dialog/define.ts b/packages/web-components/src/dialog/define.ts new file mode 100644 index 0000000000000..55ac9cde84735 --- /dev/null +++ b/packages/web-components/src/dialog/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './dialog.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/dialog/dialog.definition.ts b/packages/web-components/src/dialog/dialog.definition.ts new file mode 100644 index 0000000000000..103ccc7ab3e0d --- /dev/null +++ b/packages/web-components/src/dialog/dialog.definition.ts @@ -0,0 +1,17 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Dialog } from './dialog.js'; +import { template } from './dialog.template.js'; +import { styles } from './dialog.styles.js'; + +/** + * The Fluent Dialog Element + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = Dialog.compose({ + name: `${FluentDesignSystem.prefix}-dialog`, + template, + styles, +}); diff --git a/packages/web-components/src/dialog/dialog.options.ts b/packages/web-components/src/dialog/dialog.options.ts new file mode 100644 index 0000000000000..d2e3dc39941b1 --- /dev/null +++ b/packages/web-components/src/dialog/dialog.options.ts @@ -0,0 +1,13 @@ +import type { ValuesOf } from '@microsoft/fast-foundation/utilities.js'; + +/** + * Dialog modal type + * @public + */ +export const DialogModalType = { + modal: 'modal', + nonModal: 'non-modal', + alert: 'alert', +} as const; + +export type DialogModalType = ValuesOf; diff --git a/packages/web-components/src/dialog/dialog.stories.ts b/packages/web-components/src/dialog/dialog.stories.ts new file mode 100644 index 0000000000000..4435b669b5fd8 --- /dev/null +++ b/packages/web-components/src/dialog/dialog.stories.ts @@ -0,0 +1,636 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../helpers.stories.js'; +import type { Dialog as FluentDialog } from './dialog.js'; +import './define.js'; +import '../button/define.js'; +import '../text/define.js'; +import { DialogModalType } from './dialog.options.js'; + +type DialogStoryArgs = Args & FluentDialog; +type DialogStoryMeta = Meta; + +const dismissed20Regular = html` + +`; + +const dismissCircle20Regular = html``; + +const closeDialog = (e: Event, id: string, dismissed: boolean = false) => { + const dialog = document.getElementById(id) as FluentDialog; + dialog.hide(dismissed); +}; + +const openDialog = (e: Event, id: string) => { + const dialog = document.getElementById(id) as FluentDialog; + dialog.show(); +}; + +const openDialogControlled = (e: Event, id: string) => { + const dialog = document.getElementById(id) as FluentDialog; + dialog.setAttribute('open', ''); +}; + +const closeDialogControlled = (e: Event, id: string) => { + const dialog = document.getElementById(id) as FluentDialog; + dialog.removeAttribute('open'); +}; + +const dialogTemplate = html` + +
+ openDialog(e, 'dialog-default')}>Open Dialog + + Dialog + +

+ The dialog component is a window overlaid on either the primary window or another dialog window. Windows under + a modal dialog are inert. That is, users cannot interact with content outside an active dialog window. +

+
+
+ fluent-dialog + Close Dialog + Do Something +
+
+`; + +export default { + title: 'Components/Dialog', + args: { + modalType: DialogModalType.modal, + }, + argTypes: { + modalType: { + description: + 'modal: When this type of dialog is open, the rest of the page is dimmed out and cannot be interacted with. The tab sequence is kept within the dialog and moving the focus outside the dialog will imply closing it. This is the default type of the component.

non-modal: When a non-modal dialog is open, the rest of the page is not dimmed out and users can interact with the rest of the page. This also implies that the tab focus can move outside the dialog when it reaches the last focusable element.

alert: A special type of modal dialog that interrupts the users workflow to communicate an important message or ask for a decision. Unlike a typical modal dialog, the user must take an action through the options given to dismiss the dialog, and it cannot be dismissed through the dimmed background.', + table: { + defaultValue: { summary: DialogModalType.modal }, + }, + control: { + type: 'select', + options: Object.values(DialogModalType), + }, + defaultValue: DialogModalType.modal, + }, + noTitleAction: { + description: + 'Used to opt out of rendering the default title action that is rendered when the dialog typeis set to non-modal', + table: { + defaultValue: { summary: false }, + }, + control: { + type: 'boolean', + }, + defaultValue: false, + }, + open: { + description: 'Controls the open state of the dialog', + table: { + defaultValue: { summary: false }, + }, + }, + onOpenChange: { + description: + 'Event fired when the component transitions from its open state.

event: A CustomEvent emitted when the open state changes.

detail: An object containing relevant information, such as the open value and the type of interaction that triggered the event.', + }, + }, +} as DialogStoryMeta; + +export const Default = renderComponent(dialogTemplate).bind({}); + +export const NonModal = renderComponent(html` +
+ + + A non-modal dialog by default presents no backdrop, allowing elements outside of the dialog to be interacted with. + A non-modal dialog will present by default a close button. + + +
+

Note: if an element outside of the dialog is focused then it will not be possible to close the dialog with the Escape key.

+
+ modal-type="non-modal" +
+ + openDialog(e, 'dialog-nonmodal')}>Open Dialog + +
Non-modal
+ +

+ A non-modal dialog by default presents no backdrop, allowing elements outside of the dialog to be interacted with. + + A non-moda dialog will present by default a closeButton. +

+ +

Note: if an element outside of the dialog is focused then it will not be possible to close the dialog with the Escape key.

+ modal-type="non-modal" + Close Dialog + Do Something +
+
+`); + +export const Modal = renderComponent(html` +
+ +

+ A modal is a type of dialog that temporarily halts the main workflow to convey a significant message or require + user interaction. By default, interactions such as clicking outside the dialog or pressing the Escape key will + close the modal-dialog, resuming the user's interaction with the main content. +

+
+
+ modal-type="modal" +
+ openDialog(e, 'dialog-modal')}>Open Dialog + +
Modal
+
+ A modal is a type of dialog that temporarily halts the main workflow to convey a significant message or require + user interaction. By default, interactions such as clicking outside the dialog or pressing the Escape key will + close the modal-dialog, resuming the user's interaction with the main content. +
+
+ modal-type="modal" + Close Dialog + Do Something +
+
+`); + +export const Alert = renderComponent(html` +
+ +

+ An alert is a type of modal-dialog that interrupts the user's workflow to communicate an important message and + acquire a response. By default clicking on backdrop and pressing Escape will not dismiss an alert dialog. +

+
+
+ modal-type="alert" + +
+ openDialog(e, 'dialog-alert')}>Open Dialog + +
Alert
+
+ An alert is a type of modal-dialog that interrupts the user's workflow to communicate an important message and + acquire a response. By default clicking on backdrop and pressing Escape will not dismiss an alert dialog. +
+
+ modal-type="alert" + Close Dialog + Do Something +
+
+`); + +export const Actions = renderComponent(html` +
+

+ A dialog should have no more than + two + actions. +

+ + However, if required, you can populate the action slot with any number of buttons as needed. +
+ slot="action" +
+ openDialog(e, 'dialog-fluidactions')}>Open Dialog + +
Actions
+ + ${dismissed20Regular} + +
+ + A dialog should have no more than + two + footer actions. + +
+ + However, if required, you can populate the action slot with any number of buttons as needed. +
+ slot="action" +
+
+ + Something + Something Else + + Close Dialog + Something Else Entirely +
+
+`); + +export const TitleCustomAction = renderComponent(html` +
+ + By default a non-modal dialog renders a dismiss button with a close icon. + +
+ + + This slot can be customized to add a different kind of action, that it'll be available in any kind of dialog, + ignoring the modalType property, here's an example replacing the simple close icon with a fluent button using a + different icon. + + +
+ slot="title-action" +
+ openDialog(e, 'dialog-titlecustomaction')}>Open Dialog + +
Title Custom Action
+ + ${dismissCircle20Regular} + +
+ + By default a non-modal dialog renders a dismiss button with a close icon. + +
+ + + This slot can be customized to add a different kind of action, that it'll be available in any kind of + dialog, ignoring the modalType property, here's an example replacing the simple close icon with a fluent + button using a different icon. + + +
+ slot="title-action" +
+
+ + Close Dialog + Do Something +
+
+`); + +export const NoTitleAction = renderComponent(html` +
+

The no-title-action attribute can be provided to opt out of rendering any title action.

+
+ no-title-action +
+ openDialog(e, 'dialog-notitleaction')}>Open Dialog + +
No Title Action
+
+ +

The no-title-action attribute can be provided to opt out of rendering any title action.

+
+ no-title-action +
+
+ + Close Dialog + Do Something +
+
+`); + +export const ControlledAndUncontrolled = renderComponent(html` +
+ + + Employ the open attribute to dictate the dialog's visibility state. This method offers a declarative approach, + where the dialog's visibility is determined by the presence or absence of the external open attribute, ensuring + the state is managed outside the component. + + +
+ open +
+ openDialogControlled(e, 'dialog-controlled')}> + Open Controlled Dialog + +
+
+ + + Utilize the show and hide methods to manage the dialog's visibility. This approach allows the dialog to handle + its state internally, giving you a direct and programmatic way to toggle its display without relying on external + attributes. + + +
+ Dialog.show() + Dialog.hide() +
+ openDialog(e, 'dialog-uncontrolled')}>Open Uncontrolled Dialog +
+ +
Controlled Dialog
+ + ${dismissed20Regular} + +
+ + + Employ the open attribute to dictate the dialog's visibility state. This method offers a declarative + approach, where the dialog's visibility is determined by the presence or absence of the external open + attribute, ensuring the state is managed outside the component. + + + open +
+
+ + + Close Controlled Dialog + + Do Something +
+ +
Uncontrolled Dialog
+ + ${dismissed20Regular} + +
+ + + Utilize the show and hide methods to manage the dialog's visibility. This approach + allows the dialog to handle its state internally, giving you a direct and programmatic way to toggle its + display without relying on external attributes. + + +
+ Dialog.show() + Dialog.hide() +
+
+ + + Close Uncontrolled Dialog + + Do Something +
+
+`); + +export const TwoColumnLayout = renderComponent(html` +
+

+ The dialog is designed with flexibility in mind, accommodating multiple column layouts within its structure. +

+
+ openDialog(e, 'dialog-twocolumn')}>Open Dialog + +
Welcome!
+
+

+ The dialog is designed with flexibility in mind, accommodating multiple column layouts within its structure. +

+
+
+
+ + image layout story + +
+
+

Don't have an account? Sign up now!

+
+ + Email + +
+ + Username + +
+ + Password + +
+
+
+ + Cancel + Sign Up +
+
+`); + +export const RTL = renderComponent(html` +
+

+ The dialog component seamlessly supports both Right-to-Left (RTL) and Left-to-Right (LTR) text directions, + ensuring flexibility for various language orientations. +

+
+ openDialog(e, 'dialog-rtl')}>Open Dialog + + +
أهلاً!
+ + ${dismissed20Regular} + +

هذا المكون يدعم كلاً من LTR و RTL.

+ + إلغاء + قم بشيء +
+
+`); + +export const ScrollingLongContent = renderComponent(html` +
+

+ By default content provided in the default slot should grow until it fits viewport size, overflowed content will + be scrollable +

+
+ openDialog(e, 'dialog-longcontent')}>Open Dialog + +
Scrolling Long Content
+ + ${dismissed20Regular} + +

+ By default content provided in the default slot should grow until it fits viewport size, overflowed content + will be scrollable +

+
+
+ +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce nec lectus non lorem iaculis luctus. Proin ac + dolor eget enim commodo pretium. Duis ut nibh ac metus interdum finibus. Integer maximus ante a tincidunt + pretium. Aliquam erat volutpat. Sed nec ante vel lectus dignissim commodo id ut elit. Curabitur ullamcorper + sapien id mauris interdum, ac placerat mi malesuada. Duis aliquam, dolor eget facilisis mollis, ante leo + tincidunt quam, vel convallis ipsum turpis et turpis. Mauris fermentum neque nec tortor semper tempus. Integer + malesuada, nunc ac cursus facilisis, lectus mauris interdum erat, in vulputate risus velit in neque. Etiam + volutpat ante nec fringilla tempus. Quisque et lobortis dolor. Fusce sit amet odio sed ipsum fringilla auctor. + Suspendisse faucibus tellus in luctus hendrerit. Vestibulum euismod velit non laoreet feugiat. Nam sit amet + velit urna. Cras consectetur tempor sem, in suscipit sem ultrices id. Vivamus id felis fringilla, scelerisque + nulla non, aliquam leo. In pharetra mauris ut enim ullamcorper, id suscipit quam ullamcorper. Quisque + tincidunt, felis nec congue elementum, mauris est finibus ex, ut volutpat ante est nec est. Aliquam tempor, + turpis ac scelerisque dignissim, metus velit rutrum sem, eget efficitur mauris erat in metus. Vestibulum in + urna massa. Donec eleifend leo at dui convallis aliquet. Integer eleifend, velit ut consequat tempus, enim + elit ultricies diam, at congue enim enim id nunc. Nullam fringilla bibendum nulla, at lacinia sem bibendum + eget. Nunc posuere ipsum sed enim facilisis efficitur. Pellentesque id semper mi, a feugiat sem. Nunc + interdum, leo ut tincidunt consectetur, nunc mauris accumsan nulla, vel ultricies velit erat nec sapien. + Praesent eleifend ex at odio scelerisque cursus. Morbi eget tellus sed sapien scelerisque cursus at a ante. + Sed venenatis vehicula erat eu feugiat. Ut eu elit vitae urna tincidunt pulvinar nec at nunc. Vestibulum eget + tristique sapien. Sed egestas sapien vel ante viverra pharetra. Cras sit amet felis at nulla tincidunt euismod + vitae et justo. Duis nec rutrum lectus, nec lobortis quam. Pellentesque habitant morbi tristique senectus et + netus et malesuada fames ac turpis egestas. Sed ac ex condimentum, consectetur felis non, maximus odio. Sed + mattis arcu id justo fringilla, a tristique purus vestibulum. Nulla nec fringilla quam. Sed ac elit ac sem + posuere cursus nec vitae mauris. Suspendisse nec pulvinar risus. Sed a tincidunt elit, in gravida tortor. + Quisque sollicitudin lectus vel interdum tempor. Fusce dictum fermentum sem sed suscipit. Vivamus sollicitudin + ex turpis, sit amet consequat leo auctor at. Donec fermentum aliquet lectus, sit amet efficitur nibh + pellentesque et. Curabitur dapibus quam vitae lectus pellentesque, vitae varius massa facilisis. Quisque + consectetur eros a arcu cursus fringilla. Fusce efficitur auctor nibh, nec sollicitudin eros semper eget. Cras + a elit ut tortor semper volutpat eu vel nunc. Duis dapibus quam risus, ac tristique nisl aliquam eu. Curabitur + vel ipsum non nunc euismod fringilla vel a lorem. Curabitur viverra magna ac justo fringilla, eu vestibulum + purus finibus. Donec elementum volutpat libero, in tempus massa convallis vitae. Curabitur vitae mauris id + urna dictum pharetra. Nullam vehicula arcu arcu, vitae elementum enim tincidunt at. Duis eleifend, lorem a + efficitur facilisis, nulla dolor finibus orci, et ullamcorper orci ex ac purus. Aenean sem lectus, malesuada + id magna id, facilisis condimentum nibh. Cras tempor neque mi, sit amet suscipit libero consectetur non. + Nullam id eleifend mauris. Mauris iaculis lectus eu scelerisque efficitur. In id suscipit libero. Donec + condimentum, purus ac laoreet facilisis, risus lorem facilisis neque, id volutpat felis mi eget metus. Nulla + facilisi. Donec consequat tincidunt nunc sed elementum. Integer consectetur tristique orci, ut congue justo + pellentesque eu. Fusce faucibus iaculis mauris, eu lobortis orci egestas eget. Nullam nec arcu bibendum, + cursus diam ac, facilisis enim. Nulla facilisi. Curabitur lacinia odio mauris, a gravida nisi volutpat in. + Aliquam at maximus felis. Vestibulum convallis dignissim urna id gravida. +

+
+ Close Dialog + Do Something +
+
+`); diff --git a/packages/web-components/src/dialog/dialog.styles.ts b/packages/web-components/src/dialog/dialog.styles.ts new file mode 100644 index 0000000000000..5185d9468f022 --- /dev/null +++ b/packages/web-components/src/dialog/dialog.styles.ts @@ -0,0 +1,121 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + borderRadiusXLarge, + colorBackgroundOverlay, + colorNeutralBackground1, + colorNeutralForeground1, + colorTransparentStroke, + fontFamilyBase, + fontSizeBase300, + fontSizeBase500, + fontWeightRegular, + fontWeightSemibold, + lineHeightBase300, + lineHeightBase500, + shadow64, + spacingHorizontalS, + spacingHorizontalXXL, + spacingVerticalS, + spacingVerticalXXL, + strokeWidthThin, +} from '../theme/design-tokens.js'; + +/** Dialog styles + * @public + */ +export const styles = css` + ${display('flex')} + + :host { + --dialog-backdrop: ${colorBackgroundOverlay}; + } + + dialog { + background: ${colorNeutralBackground1}; + border: ${strokeWidthThin} solid ${colorTransparentStroke}; + z-index: 2; + margin: auto auto; + max-width: 100%; + width: 100vw; + border-radius: ${borderRadiusXLarge}; + box-shadow: ${shadow64}; + max-height: 100vh; + height: fit-content; + overflow: unset; + position: fixed; + inset: 0; + padding: 0; + } + + dialog::backdrop { + background: var(--dialog-backdrop, rgba(0, 0, 0, 0.4)); + } + + .root { + box-sizing: border-box; + display: flex; + flex-direction: column; + overflow: unset; + max-height: calc(100vh - 48px); + padding: ${spacingVerticalXXL} ${spacingHorizontalXXL}; + } + + .title { + font-size: ${fontSizeBase500}; + line-height: ${lineHeightBase500}; + font-weight: ${fontWeightSemibold}; + font-family: ${fontFamilyBase}; + color: ${colorNeutralForeground1}; + margin-bottom: ${spacingVerticalS}; + display: flex; + justify-content: space-between; + align-items: flex-start; + column-gap: 8px; + } + + .content { + vertical-align: top; + min-height: 32px; + color: ${colorNeutralForeground1}; + font-size: ${fontSizeBase300}; + line-height: ${lineHeightBase300}; + font-weight: ${fontWeightRegular}; + font-family: ${fontFamilyBase}; + overflow-y: auto; + box-sizing: border-box; + } + + .actions { + display: flex; + grid-column-start: 1; + flex-direction: column; + max-width: 100vw; + row-gap: ${spacingVerticalS}; + padding-top: ${spacingVerticalXXL}; + justify-self: stretch; + width: 100%; + } + ::slotted([slot='action']) { + width: 100%; + } + + @media screen and (min-width: 480px) { + ::slotted([slot='action']) { + width: fit-content; + } + dialog { + max-width: 600px; + width: 100%; + } + .actions { + display: flex; + flex-direction: row; + justify-content: flex-end; + align-items: center; + column-gap: ${spacingHorizontalS}; + padding-top: ${spacingVerticalS}; + box-sizing: border-box; + } + } +`; diff --git a/packages/web-components/src/dialog/dialog.template.ts b/packages/web-components/src/dialog/dialog.template.ts new file mode 100644 index 0000000000000..fcc54dba0d3c8 --- /dev/null +++ b/packages/web-components/src/dialog/dialog.template.ts @@ -0,0 +1,67 @@ +import { elements, ElementViewTemplate, html, ref, slotted, when } from '@microsoft/fast-element'; +import type { Dialog } from './dialog.js'; +import { DialogModalType } from './dialog.options.js'; + +const dismissed16Regular = html.partial(` + `); + +/** + * Template for the Dialog component + * @public + */ +export const template: ElementViewTemplate = html` + +`; diff --git a/packages/web-components/src/dialog/dialog.ts b/packages/web-components/src/dialog/dialog.ts new file mode 100644 index 0000000000000..4585bc3f28aa6 --- /dev/null +++ b/packages/web-components/src/dialog/dialog.ts @@ -0,0 +1,400 @@ +import { attr, FASTElement, observable, Updates } from '@microsoft/fast-element'; +import { isTabbable } from 'tabbable'; +import { keyEscape, keyTab } from '@microsoft/fast-web-utilities'; +import { Button as FluentButton } from '../button/button.js'; +import { DialogModalType } from './dialog.options.js'; + +/** + * Dialog component that extends the FASTElement class. + * + * @public + * @extends FASTElement + */ +export class Dialog extends FASTElement { + /** + * @private + * Indicates whether focus is being trapped within the dialog + */ + private isTrappingFocus: boolean = false; + + /** + * @public + * Lifecycle method called when the element is connected to the DOM + */ + public connectedCallback(): void { + super.connectedCallback(); + document.addEventListener('keydown', this.handleDocumentKeydown); + Updates.enqueue(() => { + this.updateTrapFocus(); + this.setComponent(); + }); + } + + /** + * @public + * Lifecycle method called when the element is disconnected from the DOM + */ + public disconnectedCallback(): void { + super.disconnectedCallback(); + document.removeEventListener('keydown', this.handleDocumentKeydown); + this.updateTrapFocus(false); + } + + /** + * @public + * The dialog element + */ + @observable + public dialog!: HTMLDialogElement; + + /** + * @public + * The title action elements + */ + @observable + public titleAction: HTMLElement[] = []; + + /** + * @public + * The default title action button + */ + @observable + public defaultTitleAction?: FluentButton; + + /** + * @public + * The ID of the element that describes the dialog + */ + @attr({ attribute: 'aria-describedby' }) + public ariaDescribedby?: string; + + /** + * @public + * The ID of the element that labels the dialog + */ + @attr({ attribute: 'aria-labelledby' }) + public ariaLabelledby?: string; + + /** + * @public + * The type of the dialog modal + */ + @attr({ attribute: 'modal-type' }) + public modalType: DialogModalType = DialogModalType.modal; + + /** + * @public + * Indicates whether the dialog is open + */ + @attr({ mode: 'boolean' }) + public open: boolean = false; + + /** + * @public + * Indicates whether the dialog has a title action + */ + @attr({ mode: 'boolean', attribute: 'no-title-action' }) + public noTitleAction: boolean = false; + + /** + * @private + * Indicates whether focus should be trapped within the dialog + */ + private trapFocus: boolean = false; + + /** + * @public + * Method called when the 'open' attribute changes + */ + public openChanged(oldValue: boolean, newValue: boolean): void { + if (newValue !== oldValue) { + if (newValue && !oldValue) { + this.show(); + } else if (!newValue && oldValue) { + this.hide(); + } + } + } + + /** + * @public + * Method called when the 'modalType' attribute changes + */ + public modalTypeChanged(oldValue: DialogModalType, newValue: DialogModalType): void { + if (newValue !== oldValue) { + if (newValue == DialogModalType.alert || newValue == DialogModalType.modal) { + this.trapFocus = true; + } else { + this.trapFocus = false; + } + } + } + + /** + * @public + * Method to set the component's state based on its attributes + */ + public setComponent(): void { + if (this.modalType == DialogModalType.modal || this.modalType == DialogModalType.alert) { + this.trapFocus = true; + } else { + this.trapFocus = false; + } + } + + /** + * @public + * Method to emit an event when the dialog's open state changes + * @param dismissed - Indicates whether the dialog was dismissed + */ + public onOpenChangeEvent = (dismissed: boolean = false): void => { + this.$emit('onOpenChange', { open: this.dialog.open, dismissed: dismissed }); + }; + + /** + * @public + * Method to show the dialog + */ + public show(): void { + Updates.enqueue(() => { + if (this.modalType === DialogModalType.alert || this.modalType === DialogModalType.modal) { + this.dialog.showModal(); + this.open = true; + this.updateTrapFocus(true); + } else if (this.modalType === DialogModalType.nonModal) { + this.dialog.show(); + this.open = true; + } + this.onOpenChangeEvent(); + }); + } + + /** + * @public + * Method to hide the dialog + * @param dismissed - Indicates whether the dialog was dismissed + */ + public hide(dismissed: boolean = false): void { + this.dialog.close(); + this.open = false; + this.onOpenChangeEvent(dismissed); + } + + /** + * @public + * Method to dismiss the dialog + */ + public dismiss(): void { + if (this.modalType === DialogModalType.alert) { + return; + } + this.hide(true); + } + + /** + * @public + * Handles click events on the dialog + * @param event - The click event + * @returns boolean + */ + public handleClick(event: Event): boolean { + event.preventDefault(); + if (this.dialog.open && this.modalType !== DialogModalType.alert && event.target === this.dialog) { + this.dismiss(); + } + return true; + } + + /** + * @public + * Handles keydown events on the dialog + * @param e - The keydown event + * @returns boolean | void + */ + public handleKeydown = (e: KeyboardEvent): boolean | void => { + if (e.defaultPrevented) { + return; + } + switch (e.key) { + case keyEscape: + if (this.modalType !== DialogModalType.alert) { + this.hide(true); + this.$emit('dismiss'); + } + break; + default: + return true; + } + }; + + /** + * @private + * Handles keydown events on the document + * @param e - The keydown event + */ + private handleDocumentKeydown = (e: KeyboardEvent): void => { + if (!e.defaultPrevented && this.dialog.open) { + switch (e.key) { + case keyTab: + this.handleTabKeyDown(e); + break; + } + } + }; + + /** + * @private + * Handles tab keydown events + * @param e - The keydown event + */ + private handleTabKeyDown = (e: KeyboardEvent): void => { + if (!this.trapFocus || !this.dialog.open) { + return; + } + + const bounds: (HTMLElement | SVGElement)[] = this.getTabQueueBounds(); + + if (bounds.length === 1) { + bounds[0].focus(); + e.preventDefault(); + return; + } + + if (e.shiftKey && e.target === bounds[0]) { + bounds[bounds.length - 1].focus(); + e.preventDefault(); + } else if (!e.shiftKey && e.target === bounds[bounds.length - 1]) { + bounds[0].focus(); + e.preventDefault(); + } + + return; + }; + + /** + * @private + * Gets the bounds of the tab queue + * @returns (HTMLElement | SVGElement)[] + */ + private getTabQueueBounds = (): (HTMLElement | SVGElement)[] => { + const bounds: HTMLElement[] = []; + + return Dialog.reduceTabbableItems(bounds, this); + }; + + /** + * @private + * Focuses the first element in the tab queue + */ + private focusFirstElement = (): void => { + const bounds: (HTMLElement | SVGElement)[] = this.getTabQueueBounds(); + + if (bounds.length > 0) { + bounds[0].focus(); + } else { + if (this.dialog instanceof HTMLElement) { + this.dialog.focus(); + } + } + }; + + /** + * @private + * Determines if focus should be forced + * @param currentFocusElement - The currently focused element + * @returns boolean + */ + private shouldForceFocus = (currentFocusElement: Element | null): boolean => { + return this.isTrappingFocus && !this.contains(currentFocusElement); + }; + + /** + * @private + * Determines if focus should be trapped + * @returns boolean + */ + private shouldTrapFocus = (): boolean => { + return this.trapFocus && this.dialog.open; + }; + + /** + * @private + * Handles focus events on the document + * @param e - The focus event + */ + private handleDocumentFocus = (e: Event): void => { + if (!e.defaultPrevented && this.shouldForceFocus(e.target as HTMLElement)) { + this.focusFirstElement(); + e.preventDefault(); + } + }; + + /** + * @private + * Updates the state of focus trapping + * @param shouldTrapFocusOverride - Optional override for whether focus should be trapped + */ + private updateTrapFocus = (shouldTrapFocusOverride?: boolean): void => { + const shouldTrapFocus = shouldTrapFocusOverride === undefined ? this.shouldTrapFocus() : shouldTrapFocusOverride; + + if (shouldTrapFocus && !this.isTrappingFocus) { + this.isTrappingFocus = true; + // Add an event listener for focusin events if we are trapping focus + document.addEventListener('focusin', this.handleDocumentFocus); + Updates.enqueue(() => { + if (this.shouldForceFocus(document.activeElement)) { + this.focusFirstElement(); + } + }); + } else if (!shouldTrapFocus && this.isTrappingFocus) { + this.isTrappingFocus = false; + // remove event listener if we are not trapping focus + document.removeEventListener('focusin', this.handleDocumentFocus); + } + }; + + /** + * @private + * Reduces the list of tabbable items + * @param elements - The current list of elements + * @param element - The element to consider adding to the list + * @returns HTMLElement[] + */ + private static reduceTabbableItems(elements: HTMLElement[], element: FASTElement): HTMLElement[] { + if (element.getAttribute('tabindex') === '-1') { + return elements; + } + + if (isTabbable(element) || (Dialog.isFocusableFastElement(element) && Dialog.hasTabbableShadow(element))) { + elements.push(element); + return elements; + } + + return Array.from(element.children).reduce( + (elements, currentElement) => Dialog.reduceTabbableItems(elements, currentElement as FASTElement), + elements, + ); + } + + /** + * @private + * Determines if an element is a focusable FASTElement + * @param element - The element to check + * @returns boolean + */ + private static isFocusableFastElement(element: FASTElement): boolean { + return !!element.$fastController?.definition.shadowOptions?.delegatesFocus; + } + + /** + * @private + * Determines if an element has a tabbable shadow + * @param element - The element to check + * @returns boolean + */ + private static hasTabbableShadow(element: FASTElement) { + return Array.from(element.shadowRoot?.querySelectorAll('*') ?? []).some(x => { + return isTabbable(x); + }); + } +} diff --git a/packages/web-components/src/dialog/index.ts b/packages/web-components/src/dialog/index.ts new file mode 100644 index 0000000000000..12f8a223acb9b --- /dev/null +++ b/packages/web-components/src/dialog/index.ts @@ -0,0 +1,4 @@ +export * from './dialog.js'; +export { definition as DialogDefinition } from './dialog.definition.js'; +export { template as DialogTemplate } from './dialog.template.js'; +export { styles as DialogStyles } from './dialog.styles.js'; diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index 92750616f0785..a5d24a242b792 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -7,6 +7,7 @@ export * from './button/index.js'; export * from './checkbox/index.js'; export * from './compound-button/index.js'; export * from './counter-badge/index.js'; +export * from './dialog/index.js'; export * from './divider/index.js'; export * from './image/index.js'; export * from './label/index.js'; From df3b8e269accd9c60ff721422198fb3797df4375 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Thu, 26 Oct 2023 04:16:56 +0000 Subject: [PATCH 169/203] applying package updates --- apps/vr-tests-web-components/package.json | 2 +- ...ents-c3eff1b3-5486-4127-9d4b-c9d6d05fdb24.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 5 files changed, 27 insertions(+), 10 deletions(-) delete mode 100644 change/@fluentui-web-components-c3eff1b3-5486-4127-9d4b-c9d6d05fdb24.json diff --git a/apps/vr-tests-web-components/package.json b/apps/vr-tests-web-components/package.json index ecbff995bffc1..a5b04fb6f8652 100644 --- a/apps/vr-tests-web-components/package.json +++ b/apps/vr-tests-web-components/package.json @@ -23,7 +23,7 @@ "dependencies": { "@fluentui/react-button": "^9.2.3", "@fluentui/react-storybook-addon": "*", - "@fluentui/web-components": "3.0.0-beta.5", + "@fluentui/web-components": "3.0.0-beta.6", "tslib": "^2.1.0" } } diff --git a/change/@fluentui-web-components-c3eff1b3-5486-4127-9d4b-c9d6d05fdb24.json b/change/@fluentui-web-components-c3eff1b3-5486-4127-9d4b-c9d6d05fdb24.json deleted file mode 100644 index f15f2159a265d..0000000000000 --- a/change/@fluentui-web-components-c3eff1b3-5486-4127-9d4b-c9d6d05fdb24.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat(dialog): add dialog web component", - "packageName": "@fluentui/web-components", - "email": "brian.christopher.brady@gmail.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index b26a12d71cae8..2794fe96a596d 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Thu, 26 Oct 2023 04:16:51 GMT", + "tag": "@fluentui/web-components_v3.0.0-beta.6", + "version": "3.0.0-beta.6", + "comments": { + "prerelease": [ + { + "author": "brian.christopher.brady@gmail.com", + "package": "@fluentui/web-components", + "commit": "dd16c56adf42b8f2771907749d3f8fde8eb52f4e", + "comment": "feat(dialog): add dialog web component" + } + ] + } + }, { "date": "Thu, 19 Oct 2023 04:18:07 GMT", "tag": "@fluentui/web-components_v3.0.0-beta.5", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index ff2fe09bc138a..aa13f3ed6887c 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Thu, 19 Oct 2023 04:18:07 GMT and should not be manually modified. +This log was last generated on Thu, 26 Oct 2023 04:16:51 GMT and should not be manually modified. +## [3.0.0-beta.6](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-beta.6) + +Thu, 26 Oct 2023 04:16:51 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-beta.5..@fluentui/web-components_v3.0.0-beta.6) + +### Changes + +- feat(dialog): add dialog web component ([PR #28569](https://github.com/microsoft/fluentui/pull/28569) by brian.christopher.brady@gmail.com) + ## [3.0.0-beta.5](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-beta.5) Thu, 19 Oct 2023 04:18:07 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 2e09e55b8d680..d4aaffb01b9d0 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -1,7 +1,7 @@ { "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 885ceb10c77ea706abdc6e16c3dd8be696e26c2c Mon Sep 17 00:00:00 2001 From: Danny van Velzen Date: Tue, 31 Oct 2023 15:48:04 -0700 Subject: [PATCH 170/203] Add 1es pt pipeline to web-components-v3 (#29713) --- azure-pipelines.release.web-components.yml | 107 +++++++++++---------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/azure-pipelines.release.web-components.yml b/azure-pipelines.release.web-components.yml index 9085ba2edfe27..c3ec1a5becc80 100644 --- a/azure-pipelines.release.web-components.yml +++ b/azure-pipelines.release.web-components.yml @@ -12,10 +12,16 @@ variables: skipComponentGovernanceDetection: false - name: release.web_components # Used to scope beachball to release only vnext packages value: true - - group: InfoSec-SecurityResults - name: tags value: production,externalfacing +resources: + repositories: + - repository: 1esPipelines + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release + schedules: # Triggers the nightly release # minute 0, hour 4 in UTC (5am in UTC+1), any day of month, any month, days 1-5 of week (M-F) @@ -26,60 +32,55 @@ schedules: include: - web-components-v3 -jobs: - - template: .devops/templates/compliance-job.yml - - - job: Release - dependsOn: Compliance - pool: '1ES-Host-Ubuntu' - workspace: - clean: all - steps: - - template: .devops/templates/tools.yml - - - script: | - git config user.name "Fluent UI Build" - git config user.email "fluentui-internal@service.microsoft.com" - git remote set-url origin https://$(githubUser):$(githubPAT)@github.com/microsoft/fluentui.git - displayName: Authenticate git for pushes - - - task: Bash@3 - inputs: - filePath: yarn-ci.sh - displayName: yarn - - # --only makes it only run tests (otherwise due to the missing --production arg, lage would re-run the build) - # https://github.com/microsoft/fluentui/issues/21686 - - script: | - yarn lage format:check lint test build --to @fluentui/web-components - displayName: Build, Test, Lint +extends: + template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines + parameters: + pool: + name: Azure-Pipelines-1ESPT-ExDShared + image: windows-latest + os: windows # We need windows because compliance task only run on windows. + stages: + - stage: main + jobs: + - job: Release + pool: + name: '1ES-Host-Ubuntu' + image: '1ES-PT-Ubuntu-20.04' + os: linux + workspace: + clean: all + templateContext: + outputs: + - output: pipelineArtifact + targetPath: $(System.DefaultWorkingDirectory) + artifactName: output + steps: + - template: .devops/templates/tools.yml@self - - script: | - yarn beachball publish -b origin/web-components-v3 --access public -y -n $(npmToken) --config scripts/beachball/release-web-components.config.js - git reset --hard origin/web-components-v3 - env: - GITHUB_PAT: $(githubPAT) - displayName: Publish changes and bump versions + - script: | + git config user.name "Fluent UI Build" + git config user.email "fluentui-internal@service.microsoft.com" + git remote set-url origin https://$(githubUser):$(githubPAT)@github.com/microsoft/fluentui.git + displayName: Authenticate git for pushes - - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 - displayName: 📒 Generate Manifest - inputs: - BuildDropPath: $(System.DefaultWorkingDirectory) + - task: Bash@3 + inputs: + filePath: yarn-ci.sh + displayName: yarn - - task: PublishPipelineArtifact@1 - displayName: 📒 Publish Manifest - inputs: - artifactName: SBom-$(System.JobAttempt) - targetPath: $(System.DefaultWorkingDirectory)/_manifest + # --only makes it only run tests (otherwise due to the missing --production arg, lage would re-run the build) + # https://github.com/microsoft/fluentui/issues/21686 + - script: | + yarn lage format:check lint test build --to @fluentui/web-components + displayName: Build, [test], Lint - - task: ComponentGovernanceComponentDetection@0 - displayName: 'Component governance detection' - inputs: - sourceScanPath: $(Agent.BuildDirectory) - condition: succeeded() - timeoutInMinutes: 5 - continueOnError: true + - script: | + yarn beachball publish -b origin/web-components-v3 --access public -y -n $(npmToken) --config scripts/beachball/release-web-components.config.js + git reset --hard origin/web-components-v3 + env: + GITHUB_PAT: $(githubPAT) + displayName: Publish changes and bump versions - - template: .devops/templates/cleanup.yml - parameters: - checkForModifiedFiles: false + - template: .devops/templates/cleanup.yml@self + parameters: + checkForModifiedFiles: false From 2fd75f1613d6841a3d78117844441a896c45c6bd Mon Sep 17 00:00:00 2001 From: Michael Barakat <90428651+bearcat-msft@users.noreply.github.com> Date: Thu, 30 Nov 2023 15:40:21 -0800 Subject: [PATCH 171/203] Web components V3 - updating disclaimer message on storybook intro page (#29924) * updating disclaimer * updating storybook disclaimer * tweaking disclaimer --- ...eb-components-21819dfb-c067-4641-b129-18bd5f3ac496.json | 7 +++++++ .../src/_docs/concepts/introduction.stories.mdx | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 change/@fluentui-web-components-21819dfb-c067-4641-b129-18bd5f3ac496.json diff --git a/change/@fluentui-web-components-21819dfb-c067-4641-b129-18bd5f3ac496.json b/change/@fluentui-web-components-21819dfb-c067-4641-b129-18bd5f3ac496.json new file mode 100644 index 0000000000000..4e37d0ee048be --- /dev/null +++ b/change/@fluentui-web-components-21819dfb-c067-4641-b129-18bd5f3ac496.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "Updating disclaimer on storybook", + "packageName": "@fluentui/web-components", + "email": "mibaraka@microsoft.com", + "dependentChangeType": "none" +} diff --git a/packages/web-components/src/_docs/concepts/introduction.stories.mdx b/packages/web-components/src/_docs/concepts/introduction.stories.mdx index 1c8fa5fcf8c15..90ad538494a64 100644 --- a/packages/web-components/src/_docs/concepts/introduction.stories.mdx +++ b/packages/web-components/src/_docs/concepts/introduction.stories.mdx @@ -7,7 +7,7 @@ import pkg from '../../../package.json'; Fluent UI Web Components v{pkg.version} -⚠️ These are not production-ready components and **should never be used in product**. This space is useful for testing new components whose APIs might change before final release. +⚠️ **While in Beta, breaking changes may be made based on feedback from users.** This space is useful for testing new components whose APIs might change before final release. Microsoft's [Fluent UI Web Components](https://github.com/microsoft/fluentui/tree/master/packages/web-components) is designed to help you build Fluent web apps using extensible Web Components. The package composes the `@microsoft/fast-foundation` Web Component package and styles it with the [Fluent design language](https://github.com/microsoft/fluentui). From a843edbaf3f06a228e5cb3ad211a7b75ed43b9e6 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Fri, 1 Dec 2023 04:08:54 +0000 Subject: [PATCH 172/203] applying package updates --- ...ents-21819dfb-c067-4641-b129-18bd5f3ac496.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 change/@fluentui-web-components-21819dfb-c067-4641-b129-18bd5f3ac496.json diff --git a/change/@fluentui-web-components-21819dfb-c067-4641-b129-18bd5f3ac496.json b/change/@fluentui-web-components-21819dfb-c067-4641-b129-18bd5f3ac496.json deleted file mode 100644 index 4e37d0ee048be..0000000000000 --- a/change/@fluentui-web-components-21819dfb-c067-4641-b129-18bd5f3ac496.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "Updating disclaimer on storybook", - "packageName": "@fluentui/web-components", - "email": "mibaraka@microsoft.com", - "dependentChangeType": "none" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 2794fe96a596d..5bbdeb3f0935a 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Fri, 01 Dec 2023 04:08:50 GMT", + "tag": "@fluentui/web-components_v3.0.0-beta.6", + "version": "3.0.0-beta.6", + "comments": { + "none": [ + { + "author": "mibaraka@microsoft.com", + "package": "@fluentui/web-components", + "commit": "ebe7e4837a07b1218f9f7196b5c3043c0ad4cbb3", + "comment": "Updating disclaimer on storybook" + } + ] + } + }, { "date": "Thu, 26 Oct 2023 04:16:51 GMT", "tag": "@fluentui/web-components_v3.0.0-beta.6", From e27184af8b014125c946d010836a50b8f12b19b3 Mon Sep 17 00:00:00 2001 From: Chris Holt Date: Thu, 8 Feb 2024 14:30:02 -0800 Subject: [PATCH 173/203] [web-components]: remove design token implementation in favor of platform solution (#30002) --- ...-258db20e-84e5-451e-a289-97726ba08b24.json | 7 + packages/web-components/docs/api-report.md | 844 ++++++++++-------- packages/web-components/scripts/compile.js | 3 + .../scripts/generate-tokens.cjs | 25 + .../accordion-item/accordion-item.styles.ts | 50 +- .../src/avatar/avatar.styles.ts | 200 ++--- .../web-components/src/badge/badge.styles.ts | 6 +- .../src/button/button.styles.ts | 126 +-- .../src/checkbox/checkbox.styles.ts | 74 +- .../compound-button/compound-button.styles.ts | 36 +- .../src/counter-badge/counter-badge.styles.ts | 4 +- .../src/dialog/dialog.styles.ts | 42 +- .../src/divider/divider.styles.ts | 26 +- .../web-components/src/image/image.styles.ts | 8 +- .../web-components/src/label/label.styles.ts | 28 +- .../src/menu-item/menu-item.styles.ts | 32 +- .../src/menu-list/menu-list.styles.ts | 8 +- .../src/progress-bar/progress-bar.styles.ts | 50 +- .../src/radio-group/radio-group.styles.ts | 18 +- .../web-components/src/radio/radio.styles.ts | 64 +- .../src/slider/slider.styles.ts | 45 +- .../src/spinner/spinner.styles.ts | 10 +- .../src/styles/partials/badge.partials.ts | 150 ++-- .../src/switch/switch.styles.ts | 68 +- .../src/tab-panel/tab-panel.styles.ts | 2 +- packages/web-components/src/tab/tab.styles.ts | 40 +- .../web-components/src/tabs/tabs.styles.ts | 98 +- .../src/text-input/text-input.styles.ts | 134 +-- .../web-components/src/text/text.styles.ts | 54 +- .../web-components/src/theme/design-tokens.ts | 773 ++++++++-------- .../web-components/src/theme/set-theme.ts | 7 +- .../web-components/src/theme/theme.stories.ts | 14 +- .../src/toggle-button/toggle-button.styles.ts | 48 +- 33 files changed, 1599 insertions(+), 1495 deletions(-) create mode 100644 change/@fluentui-web-components-258db20e-84e5-451e-a289-97726ba08b24.json create mode 100644 packages/web-components/scripts/generate-tokens.cjs diff --git a/change/@fluentui-web-components-258db20e-84e5-451e-a289-97726ba08b24.json b/change/@fluentui-web-components-258db20e-84e5-451e-a289-97726ba08b24.json new file mode 100644 index 0000000000000..2fde1657e7630 --- /dev/null +++ b/change/@fluentui-web-components-258db20e-84e5-451e-a289-97726ba08b24.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat: remove JS design token implementation in favor of platform css variables", + "packageName": "@fluentui/web-components", + "email": "chhol@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/docs/api-report.md b/packages/web-components/docs/api-report.md index f76ba722a496d..042a9ff09a728 100644 --- a/packages/web-components/docs/api-report.md +++ b/packages/web-components/docs/api-report.md @@ -6,7 +6,6 @@ import type { AnchorOptions as AnchorButtonOptions } from '@microsoft/fast-foundation/anchor.js'; import type { ButtonOptions } from '@microsoft/fast-foundation/button.js'; -import { CSSDesignToken } from '@microsoft/fast-foundation/design-token.js'; import { DividerOrientation } from '@microsoft/fast-foundation/divider.js'; import { DividerRole } from '@microsoft/fast-foundation/divider.js'; import { ElementStyles } from '@microsoft/fast-element'; @@ -390,22 +389,22 @@ export const BadgeStyles: ElementStyles; export const BadgeTemplate: ElementViewTemplate; // @public (undocumented) -export const borderRadiusCircular: CSSDesignToken; +export const borderRadiusCircular = "--borderRadiusCircular"; // @public (undocumented) -export const borderRadiusLarge: CSSDesignToken; +export const borderRadiusLarge = "--borderRadiusLarge"; // @public (undocumented) -export const borderRadiusMedium: CSSDesignToken; +export const borderRadiusMedium = "--borderRadiusMedium"; // @public (undocumented) -export const borderRadiusNone: CSSDesignToken; +export const borderRadiusNone = "--borderRadiusNone"; // @public (undocumented) -export const borderRadiusSmall: CSSDesignToken; +export const borderRadiusSmall = "--borderRadiusSmall"; // @public (undocumented) -export const borderRadiusXLarge: CSSDesignToken; +export const borderRadiusXLarge = "--borderRadiusXLarge"; // @public export class Button extends FASTButton { @@ -509,895 +508,895 @@ export const CheckboxStyles: ElementStyles; export const CheckboxTemplate: ElementViewTemplate; // @public (undocumented) -export const colorBackgroundOverlay: CSSDesignToken; +export const colorBackgroundOverlay = "--colorBackgroundOverlay"; // @public (undocumented) -export const colorBrandBackground: CSSDesignToken; +export const colorBrandBackground = "--colorBrandBackground"; // @public (undocumented) -export const colorBrandBackground2: CSSDesignToken; +export const colorBrandBackground2 = "--colorBrandBackground2"; // @public (undocumented) -export const colorBrandBackgroundHover: CSSDesignToken; +export const colorBrandBackgroundHover = "--colorBrandBackgroundHover"; // @public (undocumented) -export const colorBrandBackgroundInverted: CSSDesignToken; +export const colorBrandBackgroundInverted = "--colorBrandBackgroundInverted"; // @public (undocumented) -export const colorBrandBackgroundInvertedHover: CSSDesignToken; +export const colorBrandBackgroundInvertedHover = "--colorBrandBackgroundInvertedHover"; // @public (undocumented) -export const colorBrandBackgroundInvertedPressed: CSSDesignToken; +export const colorBrandBackgroundInvertedPressed = "--colorBrandBackgroundInvertedPressed"; // @public (undocumented) -export const colorBrandBackgroundInvertedSelected: CSSDesignToken; +export const colorBrandBackgroundInvertedSelected = "--colorBrandBackgroundInvertedSelected"; // @public (undocumented) -export const colorBrandBackgroundPressed: CSSDesignToken; +export const colorBrandBackgroundPressed = "--colorBrandBackgroundPressed"; // @public (undocumented) -export const colorBrandBackgroundSelected: CSSDesignToken; +export const colorBrandBackgroundSelected = "--colorBrandBackgroundSelected"; // @public (undocumented) -export const colorBrandBackgroundStatic: CSSDesignToken; +export const colorBrandBackgroundStatic = "--colorBrandBackgroundStatic"; // @public (undocumented) -export const colorBrandForeground1: CSSDesignToken; +export const colorBrandForeground1 = "--colorBrandForeground1"; // @public (undocumented) -export const colorBrandForeground2: CSSDesignToken; +export const colorBrandForeground2 = "--colorBrandForeground2"; // @public (undocumented) -export const colorBrandForegroundInverted: CSSDesignToken; +export const colorBrandForegroundInverted = "--colorBrandForegroundInverted"; // @public (undocumented) -export const colorBrandForegroundInvertedHover: CSSDesignToken; +export const colorBrandForegroundInvertedHover = "--colorBrandForegroundInvertedHover"; // @public (undocumented) -export const colorBrandForegroundInvertedPressed: CSSDesignToken; +export const colorBrandForegroundInvertedPressed = "--colorBrandForegroundInvertedPressed"; // @public (undocumented) -export const colorBrandForegroundLink: CSSDesignToken; +export const colorBrandForegroundLink = "--colorBrandForegroundLink"; // @public (undocumented) -export const colorBrandForegroundLinkHover: CSSDesignToken; +export const colorBrandForegroundLinkHover = "--colorBrandForegroundLinkHover"; // @public (undocumented) -export const colorBrandForegroundLinkPressed: CSSDesignToken; +export const colorBrandForegroundLinkPressed = "--colorBrandForegroundLinkPressed"; // @public (undocumented) -export const colorBrandForegroundLinkSelected: CSSDesignToken; +export const colorBrandForegroundLinkSelected = "--colorBrandForegroundLinkSelected"; // @public (undocumented) -export const colorBrandForegroundOnLight: CSSDesignToken; +export const colorBrandForegroundOnLight = "--colorBrandForegroundOnLight"; // @public (undocumented) -export const colorBrandForegroundOnLightHover: CSSDesignToken; +export const colorBrandForegroundOnLightHover = "--colorBrandForegroundOnLightHover"; // @public (undocumented) -export const colorBrandForegroundOnLightPressed: CSSDesignToken; +export const colorBrandForegroundOnLightPressed = "--colorBrandForegroundOnLightPressed"; // @public (undocumented) -export const colorBrandForegroundOnLightSelected: CSSDesignToken; +export const colorBrandForegroundOnLightSelected = "--colorBrandForegroundOnLightSelected"; // @public (undocumented) -export const colorBrandShadowAmbient: CSSDesignToken; +export const colorBrandShadowAmbient = "--colorBrandShadowAmbient"; // @public (undocumented) -export const colorBrandShadowKey: CSSDesignToken; +export const colorBrandShadowKey = "--colorBrandShadowKey"; // @public (undocumented) -export const colorBrandStroke1: CSSDesignToken; +export const colorBrandStroke1 = "--colorBrandStroke1"; // @public (undocumented) -export const colorBrandStroke2: CSSDesignToken; +export const colorBrandStroke2 = "--colorBrandStroke2"; // @public (undocumented) -export const colorCompoundBrandBackground: CSSDesignToken; +export const colorCompoundBrandBackground = "--colorCompoundBrandBackground"; // @public (undocumented) -export const colorCompoundBrandBackgroundHover: CSSDesignToken; +export const colorCompoundBrandBackgroundHover = "--colorCompoundBrandBackgroundHover"; // @public (undocumented) -export const colorCompoundBrandBackgroundPressed: CSSDesignToken; +export const colorCompoundBrandBackgroundPressed = "--colorCompoundBrandBackgroundPressed"; // @public (undocumented) -export const colorCompoundBrandForeground1: CSSDesignToken; +export const colorCompoundBrandForeground1 = "--colorCompoundBrandForeground1"; // @public (undocumented) -export const colorCompoundBrandForeground1Hover: CSSDesignToken; +export const colorCompoundBrandForeground1Hover = "--colorCompoundBrandForeground1Hover"; // @public (undocumented) -export const colorCompoundBrandForeground1Pressed: CSSDesignToken; +export const colorCompoundBrandForeground1Pressed = "--colorCompoundBrandForeground1Pressed"; // @public (undocumented) -export const colorCompoundBrandStroke: CSSDesignToken; +export const colorCompoundBrandStroke = "--colorCompoundBrandStroke"; // @public (undocumented) -export const colorCompoundBrandStrokeHover: CSSDesignToken; +export const colorCompoundBrandStrokeHover = "--colorCompoundBrandStrokeHover"; // @public (undocumented) -export const colorCompoundBrandStrokePressed: CSSDesignToken; +export const colorCompoundBrandStrokePressed = "--colorCompoundBrandStrokePressed"; // @public (undocumented) -export const colorNeutralBackground1: CSSDesignToken; +export const colorNeutralBackground1 = "--colorNeutralBackground1"; // @public (undocumented) -export const colorNeutralBackground1Hover: CSSDesignToken; +export const colorNeutralBackground1Hover = "--colorNeutralBackground1Hover"; // @public (undocumented) -export const colorNeutralBackground1Pressed: CSSDesignToken; +export const colorNeutralBackground1Pressed = "--colorNeutralBackground1Pressed"; // @public (undocumented) -export const colorNeutralBackground1Selected: CSSDesignToken; +export const colorNeutralBackground1Selected = "--colorNeutralBackground1Selected"; // @public (undocumented) -export const colorNeutralBackground2: CSSDesignToken; +export const colorNeutralBackground2 = "--colorNeutralBackground2"; // @public (undocumented) -export const colorNeutralBackground2Hover: CSSDesignToken; +export const colorNeutralBackground2Hover = "--colorNeutralBackground2Hover"; // @public (undocumented) -export const colorNeutralBackground2Pressed: CSSDesignToken; +export const colorNeutralBackground2Pressed = "--colorNeutralBackground2Pressed"; // @public (undocumented) -export const colorNeutralBackground2Selected: CSSDesignToken; +export const colorNeutralBackground2Selected = "--colorNeutralBackground2Selected"; // @public (undocumented) -export const colorNeutralBackground3: CSSDesignToken; +export const colorNeutralBackground3 = "--colorNeutralBackground3"; // @public (undocumented) -export const colorNeutralBackground3Hover: CSSDesignToken; +export const colorNeutralBackground3Hover = "--colorNeutralBackground3Hover"; // @public (undocumented) -export const colorNeutralBackground3Pressed: CSSDesignToken; +export const colorNeutralBackground3Pressed = "--colorNeutralBackground3Pressed"; // @public (undocumented) -export const colorNeutralBackground3Selected: CSSDesignToken; +export const colorNeutralBackground3Selected = "--colorNeutralBackground3Selected"; // @public (undocumented) -export const colorNeutralBackground4: CSSDesignToken; +export const colorNeutralBackground4 = "--colorNeutralBackground4"; // @public (undocumented) -export const colorNeutralBackground4Hover: CSSDesignToken; +export const colorNeutralBackground4Hover = "--colorNeutralBackground4Hover"; // @public (undocumented) -export const colorNeutralBackground4Pressed: CSSDesignToken; +export const colorNeutralBackground4Pressed = "--colorNeutralBackground4Pressed"; // @public (undocumented) -export const colorNeutralBackground4Selected: CSSDesignToken; +export const colorNeutralBackground4Selected = "--colorNeutralBackground4Selected"; // @public (undocumented) -export const colorNeutralBackground5: CSSDesignToken; +export const colorNeutralBackground5 = "--colorNeutralBackground5"; // @public (undocumented) -export const colorNeutralBackground5Hover: CSSDesignToken; +export const colorNeutralBackground5Hover = "--colorNeutralBackground5Hover"; // @public (undocumented) -export const colorNeutralBackground5Pressed: CSSDesignToken; +export const colorNeutralBackground5Pressed = "--colorNeutralBackground5Pressed"; // @public (undocumented) -export const colorNeutralBackground5Selected: CSSDesignToken; +export const colorNeutralBackground5Selected = "--colorNeutralBackground5Selected"; // @public (undocumented) -export const colorNeutralBackground6: CSSDesignToken; +export const colorNeutralBackground6 = "--colorNeutralBackground6"; // @public (undocumented) -export const colorNeutralBackgroundDisabled: CSSDesignToken; +export const colorNeutralBackgroundDisabled = "--colorNeutralBackgroundDisabled"; // @public (undocumented) -export const colorNeutralBackgroundInverted: CSSDesignToken; +export const colorNeutralBackgroundInverted = "--colorNeutralBackgroundInverted"; // @public (undocumented) -export const colorNeutralBackgroundInvertedDisabled: CSSDesignToken; +export const colorNeutralBackgroundInvertedDisabled = "--colorNeutralBackgroundInvertedDisabled"; // @public (undocumented) -export const colorNeutralBackgroundStatic: CSSDesignToken; +export const colorNeutralBackgroundStatic = "--colorNeutralBackgroundStatic"; // @public (undocumented) -export const colorNeutralForeground1: CSSDesignToken; +export const colorNeutralForeground1 = "--colorNeutralForeground1"; // @public (undocumented) -export const colorNeutralForeground1Hover: CSSDesignToken; +export const colorNeutralForeground1Hover = "--colorNeutralForeground1Hover"; // @public (undocumented) -export const colorNeutralForeground1Pressed: CSSDesignToken; +export const colorNeutralForeground1Pressed = "--colorNeutralForeground1Pressed"; // @public (undocumented) -export const colorNeutralForeground1Selected: CSSDesignToken; +export const colorNeutralForeground1Selected = "--colorNeutralForeground1Selected"; // @public (undocumented) -export const colorNeutralForeground1Static: CSSDesignToken; +export const colorNeutralForeground1Static = "--colorNeutralForeground1Static"; // @public (undocumented) -export const colorNeutralForeground2: CSSDesignToken; +export const colorNeutralForeground2 = "--colorNeutralForeground2"; // @public (undocumented) -export const colorNeutralForeground2BrandHover: CSSDesignToken; +export const colorNeutralForeground2BrandHover = "--colorNeutralForeground2BrandHover"; // @public (undocumented) -export const colorNeutralForeground2BrandPressed: CSSDesignToken; +export const colorNeutralForeground2BrandPressed = "--colorNeutralForeground2BrandPressed"; // @public (undocumented) -export const colorNeutralForeground2BrandSelected: CSSDesignToken; +export const colorNeutralForeground2BrandSelected = "--colorNeutralForeground2BrandSelected"; // @public (undocumented) -export const colorNeutralForeground2Hover: CSSDesignToken; +export const colorNeutralForeground2Hover = "--colorNeutralForeground2Hover"; // @public (undocumented) -export const colorNeutralForeground2Link: CSSDesignToken; +export const colorNeutralForeground2Link = "--colorNeutralForeground2Link"; // @public (undocumented) -export const colorNeutralForeground2LinkHover: CSSDesignToken; +export const colorNeutralForeground2LinkHover = "--colorNeutralForeground2LinkHover"; // @public (undocumented) -export const colorNeutralForeground2LinkPressed: CSSDesignToken; +export const colorNeutralForeground2LinkPressed = "--colorNeutralForeground2LinkPressed"; // @public (undocumented) -export const colorNeutralForeground2LinkSelected: CSSDesignToken; +export const colorNeutralForeground2LinkSelected = "--colorNeutralForeground2LinkSelected"; // @public (undocumented) -export const colorNeutralForeground2Pressed: CSSDesignToken; +export const colorNeutralForeground2Pressed = "--colorNeutralForeground2Pressed"; // @public (undocumented) -export const colorNeutralForeground2Selected: CSSDesignToken; +export const colorNeutralForeground2Selected = "--colorNeutralForeground2Selected"; // @public (undocumented) -export const colorNeutralForeground3: CSSDesignToken; +export const colorNeutralForeground3 = "--colorNeutralForeground3"; // @public (undocumented) -export const colorNeutralForeground3BrandHover: CSSDesignToken; +export const colorNeutralForeground3BrandHover = "--colorNeutralForeground3BrandHover"; // @public (undocumented) -export const colorNeutralForeground3BrandPressed: CSSDesignToken; +export const colorNeutralForeground3BrandPressed = "--colorNeutralForeground3BrandPressed"; // @public (undocumented) -export const colorNeutralForeground3BrandSelected: CSSDesignToken; +export const colorNeutralForeground3BrandSelected = "--colorNeutralForeground3BrandSelected"; // @public (undocumented) -export const colorNeutralForeground3Hover: CSSDesignToken; +export const colorNeutralForeground3Hover = "--colorNeutralForeground3Hover"; // @public (undocumented) -export const colorNeutralForeground3Pressed: CSSDesignToken; +export const colorNeutralForeground3Pressed = "--colorNeutralForeground3Pressed"; // @public (undocumented) -export const colorNeutralForeground3Selected: CSSDesignToken; +export const colorNeutralForeground3Selected = "--colorNeutralForeground3Selected"; // @public (undocumented) -export const colorNeutralForeground4: CSSDesignToken; +export const colorNeutralForeground4 = "--colorNeutralForeground4"; // @public (undocumented) -export const colorNeutralForegroundDisabled: CSSDesignToken; +export const colorNeutralForegroundDisabled = "--colorNeutralForegroundDisabled"; // @public (undocumented) -export const colorNeutralForegroundInverted: CSSDesignToken; +export const colorNeutralForegroundInverted = "--colorNeutralForegroundInverted"; // @public (undocumented) -export const colorNeutralForegroundInverted2: CSSDesignToken; +export const colorNeutralForegroundInverted2 = "--colorNeutralForegroundInverted2"; // @public (undocumented) -export const colorNeutralForegroundInvertedDisabled: CSSDesignToken; +export const colorNeutralForegroundInvertedDisabled = "--colorNeutralForegroundInvertedDisabled"; // @public (undocumented) -export const colorNeutralForegroundInvertedHover: CSSDesignToken; +export const colorNeutralForegroundInvertedHover = "--colorNeutralForegroundInvertedHover"; // @public (undocumented) -export const colorNeutralForegroundInvertedLink: CSSDesignToken; +export const colorNeutralForegroundInvertedLink = "--colorNeutralForegroundInvertedLink"; // @public (undocumented) -export const colorNeutralForegroundInvertedLinkHover: CSSDesignToken; +export const colorNeutralForegroundInvertedLinkHover = "--colorNeutralForegroundInvertedLinkHover"; // @public (undocumented) -export const colorNeutralForegroundInvertedLinkPressed: CSSDesignToken; +export const colorNeutralForegroundInvertedLinkPressed = "--colorNeutralForegroundInvertedLinkPressed"; // @public (undocumented) -export const colorNeutralForegroundInvertedLinkSelected: CSSDesignToken; +export const colorNeutralForegroundInvertedLinkSelected = "--colorNeutralForegroundInvertedLinkSelected"; // @public (undocumented) -export const colorNeutralForegroundInvertedPressed: CSSDesignToken; +export const colorNeutralForegroundInvertedPressed = "--colorNeutralForegroundInvertedPressed"; // @public (undocumented) -export const colorNeutralForegroundInvertedSelected: CSSDesignToken; +export const colorNeutralForegroundInvertedSelected = "--colorNeutralForegroundInvertedSelected"; // @public (undocumented) -export const colorNeutralForegroundOnBrand: CSSDesignToken; +export const colorNeutralForegroundOnBrand = "--colorNeutralForegroundOnBrand"; // @public (undocumented) -export const colorNeutralForegroundStaticInverted: CSSDesignToken; +export const colorNeutralForegroundStaticInverted = "--colorNeutralForegroundStaticInverted"; // @public (undocumented) -export const colorNeutralShadowAmbient: CSSDesignToken; +export const colorNeutralShadowAmbient = "--colorNeutralShadowAmbient"; // @public (undocumented) -export const colorNeutralShadowAmbientDarker: CSSDesignToken; +export const colorNeutralShadowAmbientDarker = "--colorNeutralShadowAmbientDarker"; // @public (undocumented) -export const colorNeutralShadowAmbientLighter: CSSDesignToken; +export const colorNeutralShadowAmbientLighter = "--colorNeutralShadowAmbientLighter"; // @public (undocumented) -export const colorNeutralShadowKey: CSSDesignToken; +export const colorNeutralShadowKey = "--colorNeutralShadowKey"; // @public (undocumented) -export const colorNeutralShadowKeyDarker: CSSDesignToken; +export const colorNeutralShadowKeyDarker = "--colorNeutralShadowKeyDarker"; // @public (undocumented) -export const colorNeutralShadowKeyLighter: CSSDesignToken; +export const colorNeutralShadowKeyLighter = "--colorNeutralShadowKeyLighter"; // @public (undocumented) -export const colorNeutralStencil1: CSSDesignToken; +export const colorNeutralStencil1 = "--colorNeutralStencil1"; // @public (undocumented) -export const colorNeutralStencil1Alpha: CSSDesignToken; +export const colorNeutralStencil1Alpha = "--colorNeutralStencil1Alpha"; // @public (undocumented) -export const colorNeutralStencil2: CSSDesignToken; +export const colorNeutralStencil2 = "--colorNeutralStencil2"; // @public (undocumented) -export const colorNeutralStencil2Alpha: CSSDesignToken; +export const colorNeutralStencil2Alpha = "--colorNeutralStencil2Alpha"; // @public (undocumented) -export const colorNeutralStroke1: CSSDesignToken; +export const colorNeutralStroke1 = "--colorNeutralStroke1"; // @public (undocumented) -export const colorNeutralStroke1Hover: CSSDesignToken; +export const colorNeutralStroke1Hover = "--colorNeutralStroke1Hover"; // @public (undocumented) -export const colorNeutralStroke1Pressed: CSSDesignToken; +export const colorNeutralStroke1Pressed = "--colorNeutralStroke1Pressed"; // @public (undocumented) -export const colorNeutralStroke1Selected: CSSDesignToken; +export const colorNeutralStroke1Selected = "--colorNeutralStroke1Selected"; // @public (undocumented) -export const colorNeutralStroke2: CSSDesignToken; +export const colorNeutralStroke2 = "--colorNeutralStroke2"; // @public (undocumented) -export const colorNeutralStroke3: CSSDesignToken; +export const colorNeutralStroke3 = "--colorNeutralStroke3"; // @public (undocumented) -export const colorNeutralStrokeAccessible: CSSDesignToken; +export const colorNeutralStrokeAccessible = "--colorNeutralStrokeAccessible"; // @public (undocumented) -export const colorNeutralStrokeAccessibleHover: CSSDesignToken; +export const colorNeutralStrokeAccessibleHover = "--colorNeutralStrokeAccessibleHover"; // @public (undocumented) -export const colorNeutralStrokeAccessiblePressed: CSSDesignToken; +export const colorNeutralStrokeAccessiblePressed = "--colorNeutralStrokeAccessiblePressed"; // @public (undocumented) -export const colorNeutralStrokeAccessibleSelected: CSSDesignToken; +export const colorNeutralStrokeAccessibleSelected = "--colorNeutralStrokeAccessibleSelected"; // @public (undocumented) -export const colorNeutralStrokeDisabled: CSSDesignToken; +export const colorNeutralStrokeDisabled = "--colorNeutralStrokeDisabled"; // @public (undocumented) -export const colorNeutralStrokeInvertedDisabled: CSSDesignToken; +export const colorNeutralStrokeInvertedDisabled = "--colorNeutralStrokeInvertedDisabled"; // @public (undocumented) -export const colorNeutralStrokeOnBrand: CSSDesignToken; +export const colorNeutralStrokeOnBrand = "--colorNeutralStrokeOnBrand"; // @public (undocumented) -export const colorNeutralStrokeOnBrand2: CSSDesignToken; +export const colorNeutralStrokeOnBrand2 = "--colorNeutralStrokeOnBrand2"; // @public (undocumented) -export const colorNeutralStrokeOnBrand2Hover: CSSDesignToken; +export const colorNeutralStrokeOnBrand2Hover = "--colorNeutralStrokeOnBrand2Hover"; // @public (undocumented) -export const colorNeutralStrokeOnBrand2Pressed: CSSDesignToken; +export const colorNeutralStrokeOnBrand2Pressed = "--colorNeutralStrokeOnBrand2Pressed"; // @public (undocumented) -export const colorNeutralStrokeOnBrand2Selected: CSSDesignToken; +export const colorNeutralStrokeOnBrand2Selected = "--colorNeutralStrokeOnBrand2Selected"; // @public (undocumented) -export const colorPaletteAnchorBackground2: CSSDesignToken; +export const colorPaletteAnchorBackground2 = "--colorPaletteAnchorBackground2"; // @public (undocumented) -export const colorPaletteAnchorBorderActive: CSSDesignToken; +export const colorPaletteAnchorBorderActive = "--colorPaletteAnchorBorderActive"; // @public (undocumented) -export const colorPaletteAnchorForeground2: CSSDesignToken; +export const colorPaletteAnchorForeground2 = "--colorPaletteAnchorForeground2"; // @public (undocumented) -export const colorPaletteBeigeBackground2: CSSDesignToken; +export const colorPaletteBeigeBackground2 = "--colorPaletteBeigeBackground2"; // @public (undocumented) -export const colorPaletteBeigeBorderActive: CSSDesignToken; +export const colorPaletteBeigeBorderActive = "--colorPaletteBeigeBorderActive"; // @public (undocumented) -export const colorPaletteBeigeForeground2: CSSDesignToken; +export const colorPaletteBeigeForeground2 = "--colorPaletteBeigeForeground2"; // @public (undocumented) -export const colorPaletteBerryBackground1: CSSDesignToken; +export const colorPaletteBerryBackground1 = "--colorPaletteBerryBackground1"; // @public (undocumented) -export const colorPaletteBerryBackground2: CSSDesignToken; +export const colorPaletteBerryBackground2 = "--colorPaletteBerryBackground2"; // @public (undocumented) -export const colorPaletteBerryBackground3: CSSDesignToken; +export const colorPaletteBerryBackground3 = "--colorPaletteBerryBackground3"; // @public (undocumented) -export const colorPaletteBerryBorder1: CSSDesignToken; +export const colorPaletteBerryBorder1 = "--colorPaletteBerryBorder1"; // @public (undocumented) -export const colorPaletteBerryBorder2: CSSDesignToken; +export const colorPaletteBerryBorder2 = "--colorPaletteBerryBorder2"; // @public (undocumented) -export const colorPaletteBerryBorderActive: CSSDesignToken; +export const colorPaletteBerryBorderActive = "--colorPaletteBerryBorderActive"; // @public (undocumented) -export const colorPaletteBerryForeground1: CSSDesignToken; +export const colorPaletteBerryForeground1 = "--colorPaletteBerryForeground1"; // @public (undocumented) -export const colorPaletteBerryForeground2: CSSDesignToken; +export const colorPaletteBerryForeground2 = "--colorPaletteBerryForeground2"; // @public (undocumented) -export const colorPaletteBerryForeground3: CSSDesignToken; +export const colorPaletteBerryForeground3 = "--colorPaletteBerryForeground3"; // @public (undocumented) -export const colorPaletteBlueBackground2: CSSDesignToken; +export const colorPaletteBlueBackground2 = "--colorPaletteBlueBackground2"; // @public (undocumented) -export const colorPaletteBlueBorderActive: CSSDesignToken; +export const colorPaletteBlueBorderActive = "--colorPaletteBlueBorderActive"; // @public (undocumented) -export const colorPaletteBlueForeground2: CSSDesignToken; +export const colorPaletteBlueForeground2 = "--colorPaletteBlueForeground2"; // @public (undocumented) -export const colorPaletteBrassBackground2: CSSDesignToken; +export const colorPaletteBrassBackground2 = "--colorPaletteBrassBackground2"; // @public (undocumented) -export const colorPaletteBrassBorderActive: CSSDesignToken; +export const colorPaletteBrassBorderActive = "--colorPaletteBrassBorderActive"; // @public (undocumented) -export const colorPaletteBrassForeground2: CSSDesignToken; +export const colorPaletteBrassForeground2 = "--colorPaletteBrassForeground2"; // @public (undocumented) -export const colorPaletteBrownBackground2: CSSDesignToken; +export const colorPaletteBrownBackground2 = "--colorPaletteBrownBackground2"; // @public (undocumented) -export const colorPaletteBrownBorderActive: CSSDesignToken; +export const colorPaletteBrownBorderActive = "--colorPaletteBrownBorderActive"; // @public (undocumented) -export const colorPaletteBrownForeground2: CSSDesignToken; +export const colorPaletteBrownForeground2 = "--colorPaletteBrownForeground2"; // @public (undocumented) -export const colorPaletteCornflowerBackground2: CSSDesignToken; +export const colorPaletteCornflowerBackground2 = "--colorPaletteCornflowerBackground2"; // @public (undocumented) -export const colorPaletteCornflowerBorderActive: CSSDesignToken; +export const colorPaletteCornflowerBorderActive = "--colorPaletteCornflowerBorderActive"; // @public (undocumented) -export const colorPaletteCornflowerForeground2: CSSDesignToken; +export const colorPaletteCornflowerForeground2 = "--colorPaletteCornflowerForeground2"; // @public (undocumented) -export const colorPaletteCranberryBackground2: CSSDesignToken; +export const colorPaletteCranberryBackground2 = "--colorPaletteCranberryBackground2"; // @public (undocumented) -export const colorPaletteCranberryBorderActive: CSSDesignToken; +export const colorPaletteCranberryBorderActive = "--colorPaletteCranberryBorderActive"; // @public (undocumented) -export const colorPaletteCranberryForeground2: CSSDesignToken; +export const colorPaletteCranberryForeground2 = "--colorPaletteCranberryForeground2"; // @public (undocumented) -export const colorPaletteDarkGreenBackground2: CSSDesignToken; +export const colorPaletteDarkGreenBackground2 = "--colorPaletteDarkGreenBackground2"; // @public (undocumented) -export const colorPaletteDarkGreenBorderActive: CSSDesignToken; +export const colorPaletteDarkGreenBorderActive = "--colorPaletteDarkGreenBorderActive"; // @public (undocumented) -export const colorPaletteDarkGreenForeground2: CSSDesignToken; +export const colorPaletteDarkGreenForeground2 = "--colorPaletteDarkGreenForeground2"; // @public (undocumented) -export const colorPaletteDarkOrangeBackground1: CSSDesignToken; +export const colorPaletteDarkOrangeBackground1 = "--colorPaletteDarkOrangeBackground1"; // @public (undocumented) -export const colorPaletteDarkOrangeBackground2: CSSDesignToken; +export const colorPaletteDarkOrangeBackground2 = "--colorPaletteDarkOrangeBackground2"; // @public (undocumented) -export const colorPaletteDarkOrangeBackground3: CSSDesignToken; +export const colorPaletteDarkOrangeBackground3 = "--colorPaletteDarkOrangeBackground3"; // @public (undocumented) -export const colorPaletteDarkOrangeBorder1: CSSDesignToken; +export const colorPaletteDarkOrangeBorder1 = "--colorPaletteDarkOrangeBorder1"; // @public (undocumented) -export const colorPaletteDarkOrangeBorder2: CSSDesignToken; +export const colorPaletteDarkOrangeBorder2 = "--colorPaletteDarkOrangeBorder2"; // @public (undocumented) -export const colorPaletteDarkOrangeBorderActive: CSSDesignToken; +export const colorPaletteDarkOrangeBorderActive = "--colorPaletteDarkOrangeBorderActive"; // @public (undocumented) -export const colorPaletteDarkOrangeForeground1: CSSDesignToken; +export const colorPaletteDarkOrangeForeground1 = "--colorPaletteDarkOrangeForeground1"; // @public (undocumented) -export const colorPaletteDarkOrangeForeground2: CSSDesignToken; +export const colorPaletteDarkOrangeForeground2 = "--colorPaletteDarkOrangeForeground2"; // @public (undocumented) -export const colorPaletteDarkOrangeForeground3: CSSDesignToken; +export const colorPaletteDarkOrangeForeground3 = "--colorPaletteDarkOrangeForeground3"; // @public (undocumented) -export const colorPaletteDarkRedBackground2: CSSDesignToken; +export const colorPaletteDarkRedBackground2 = "--colorPaletteDarkRedBackground2"; // @public (undocumented) -export const colorPaletteDarkRedBorderActive: CSSDesignToken; +export const colorPaletteDarkRedBorderActive = "--colorPaletteDarkRedBorderActive"; // @public (undocumented) -export const colorPaletteDarkRedForeground2: CSSDesignToken; +export const colorPaletteDarkRedForeground2 = "--colorPaletteDarkRedForeground2"; // @public (undocumented) -export const colorPaletteForestBackground2: CSSDesignToken; +export const colorPaletteForestBackground2 = "--colorPaletteForestBackground2"; // @public (undocumented) -export const colorPaletteForestBorderActive: CSSDesignToken; +export const colorPaletteForestBorderActive = "--colorPaletteForestBorderActive"; // @public (undocumented) -export const colorPaletteForestForeground2: CSSDesignToken; +export const colorPaletteForestForeground2 = "--colorPaletteForestForeground2"; // @public (undocumented) -export const colorPaletteGoldBackground2: CSSDesignToken; +export const colorPaletteGoldBackground2 = "--colorPaletteGoldBackground2"; // @public (undocumented) -export const colorPaletteGoldBorderActive: CSSDesignToken; +export const colorPaletteGoldBorderActive = "--colorPaletteGoldBorderActive"; // @public (undocumented) -export const colorPaletteGoldForeground2: CSSDesignToken; +export const colorPaletteGoldForeground2 = "--colorPaletteGoldForeground2"; // @public (undocumented) -export const colorPaletteGrapeBackground2: CSSDesignToken; +export const colorPaletteGrapeBackground2 = "--colorPaletteGrapeBackground2"; // @public (undocumented) -export const colorPaletteGrapeBorderActive: CSSDesignToken; +export const colorPaletteGrapeBorderActive = "--colorPaletteGrapeBorderActive"; // @public (undocumented) -export const colorPaletteGrapeForeground2: CSSDesignToken; +export const colorPaletteGrapeForeground2 = "--colorPaletteGrapeForeground2"; // @public (undocumented) -export const colorPaletteGreenBackground1: CSSDesignToken; +export const colorPaletteGreenBackground1 = "--colorPaletteGreenBackground1"; // @public (undocumented) -export const colorPaletteGreenBackground2: CSSDesignToken; +export const colorPaletteGreenBackground2 = "--colorPaletteGreenBackground2"; // @public (undocumented) -export const colorPaletteGreenBackground3: CSSDesignToken; +export const colorPaletteGreenBackground3 = "--colorPaletteGreenBackground3"; // @public (undocumented) -export const colorPaletteGreenBorder1: CSSDesignToken; +export const colorPaletteGreenBorder1 = "--colorPaletteGreenBorder1"; // @public (undocumented) -export const colorPaletteGreenBorder2: CSSDesignToken; +export const colorPaletteGreenBorder2 = "--colorPaletteGreenBorder2"; // @public (undocumented) -export const colorPaletteGreenBorderActive: CSSDesignToken; +export const colorPaletteGreenBorderActive = "--colorPaletteGreenBorderActive"; // @public (undocumented) -export const colorPaletteGreenForeground1: CSSDesignToken; +export const colorPaletteGreenForeground1 = "--colorPaletteGreenForeground1"; // @public (undocumented) -export const colorPaletteGreenForeground2: CSSDesignToken; +export const colorPaletteGreenForeground2 = "--colorPaletteGreenForeground2"; // @public (undocumented) -export const colorPaletteGreenForeground3: CSSDesignToken; +export const colorPaletteGreenForeground3 = "--colorPaletteGreenForeground3"; // @public (undocumented) -export const colorPaletteGreenForegroundInverted: CSSDesignToken; +export const colorPaletteGreenForegroundInverted = "--colorPaletteGreenForegroundInverted"; // @public (undocumented) -export const colorPaletteLavenderBackground2: CSSDesignToken; +export const colorPaletteLavenderBackground2 = "--colorPaletteLavenderBackground2"; // @public (undocumented) -export const colorPaletteLavenderBorderActive: CSSDesignToken; +export const colorPaletteLavenderBorderActive = "--colorPaletteLavenderBorderActive"; // @public (undocumented) -export const colorPaletteLavenderForeground2: CSSDesignToken; +export const colorPaletteLavenderForeground2 = "--colorPaletteLavenderForeground2"; // @public (undocumented) -export const colorPaletteLightGreenBackground1: CSSDesignToken; +export const colorPaletteLightGreenBackground1 = "--colorPaletteLightGreenBackground1"; // @public (undocumented) -export const colorPaletteLightGreenBackground2: CSSDesignToken; +export const colorPaletteLightGreenBackground2 = "--colorPaletteLightGreenBackground2"; // @public (undocumented) -export const colorPaletteLightGreenBackground3: CSSDesignToken; +export const colorPaletteLightGreenBackground3 = "--colorPaletteLightGreenBackground3"; // @public (undocumented) -export const colorPaletteLightGreenBorder1: CSSDesignToken; +export const colorPaletteLightGreenBorder1 = "--colorPaletteLightGreenBorder1"; // @public (undocumented) -export const colorPaletteLightGreenBorder2: CSSDesignToken; +export const colorPaletteLightGreenBorder2 = "--colorPaletteLightGreenBorder2"; // @public (undocumented) -export const colorPaletteLightGreenBorderActive: CSSDesignToken; +export const colorPaletteLightGreenBorderActive = "--colorPaletteLightGreenBorderActive"; // @public (undocumented) -export const colorPaletteLightGreenForeground1: CSSDesignToken; +export const colorPaletteLightGreenForeground1 = "--colorPaletteLightGreenForeground1"; // @public (undocumented) -export const colorPaletteLightGreenForeground2: CSSDesignToken; +export const colorPaletteLightGreenForeground2 = "--colorPaletteLightGreenForeground2"; // @public (undocumented) -export const colorPaletteLightGreenForeground3: CSSDesignToken; +export const colorPaletteLightGreenForeground3 = "--colorPaletteLightGreenForeground3"; // @public (undocumented) -export const colorPaletteLightTealBackground2: CSSDesignToken; +export const colorPaletteLightTealBackground2 = "--colorPaletteLightTealBackground2"; // @public (undocumented) -export const colorPaletteLightTealBorderActive: CSSDesignToken; +export const colorPaletteLightTealBorderActive = "--colorPaletteLightTealBorderActive"; // @public (undocumented) -export const colorPaletteLightTealForeground2: CSSDesignToken; +export const colorPaletteLightTealForeground2 = "--colorPaletteLightTealForeground2"; // @public (undocumented) -export const colorPaletteLilacBackground2: CSSDesignToken; +export const colorPaletteLilacBackground2 = "--colorPaletteLilacBackground2"; // @public (undocumented) -export const colorPaletteLilacBorderActive: CSSDesignToken; +export const colorPaletteLilacBorderActive = "--colorPaletteLilacBorderActive"; // @public (undocumented) -export const colorPaletteLilacForeground2: CSSDesignToken; +export const colorPaletteLilacForeground2 = "--colorPaletteLilacForeground2"; // @public (undocumented) -export const colorPaletteMagentaBackground2: CSSDesignToken; +export const colorPaletteMagentaBackground2 = "--colorPaletteMagentaBackground2"; // @public (undocumented) -export const colorPaletteMagentaBorderActive: CSSDesignToken; +export const colorPaletteMagentaBorderActive = "--colorPaletteMagentaBorderActive"; // @public (undocumented) -export const colorPaletteMagentaForeground2: CSSDesignToken; +export const colorPaletteMagentaForeground2 = "--colorPaletteMagentaForeground2"; // @public (undocumented) -export const colorPaletteMarigoldBackground1: CSSDesignToken; +export const colorPaletteMarigoldBackground1 = "--colorPaletteMarigoldBackground1"; // @public (undocumented) -export const colorPaletteMarigoldBackground2: CSSDesignToken; +export const colorPaletteMarigoldBackground2 = "--colorPaletteMarigoldBackground2"; // @public (undocumented) -export const colorPaletteMarigoldBackground3: CSSDesignToken; +export const colorPaletteMarigoldBackground3 = "--colorPaletteMarigoldBackground3"; // @public (undocumented) -export const colorPaletteMarigoldBorder1: CSSDesignToken; +export const colorPaletteMarigoldBorder1 = "--colorPaletteMarigoldBorder1"; // @public (undocumented) -export const colorPaletteMarigoldBorder2: CSSDesignToken; +export const colorPaletteMarigoldBorder2 = "--colorPaletteMarigoldBorder2"; // @public (undocumented) -export const colorPaletteMarigoldBorderActive: CSSDesignToken; +export const colorPaletteMarigoldBorderActive = "--colorPaletteMarigoldBorderActive"; // @public (undocumented) -export const colorPaletteMarigoldForeground1: CSSDesignToken; +export const colorPaletteMarigoldForeground1 = "--colorPaletteMarigoldForeground1"; // @public (undocumented) -export const colorPaletteMarigoldForeground2: CSSDesignToken; +export const colorPaletteMarigoldForeground2 = "--colorPaletteMarigoldForeground2"; // @public (undocumented) -export const colorPaletteMarigoldForeground3: CSSDesignToken; +export const colorPaletteMarigoldForeground3 = "--colorPaletteMarigoldForeground3"; // @public (undocumented) -export const colorPaletteMinkBackground2: CSSDesignToken; +export const colorPaletteMinkBackground2 = "--colorPaletteMinkBackground2"; // @public (undocumented) -export const colorPaletteMinkBorderActive: CSSDesignToken; +export const colorPaletteMinkBorderActive = "--colorPaletteMinkBorderActive"; // @public (undocumented) -export const colorPaletteMinkForeground2: CSSDesignToken; +export const colorPaletteMinkForeground2 = "--colorPaletteMinkForeground2"; // @public (undocumented) -export const colorPaletteNavyBackground2: CSSDesignToken; +export const colorPaletteNavyBackground2 = "--colorPaletteNavyBackground2"; // @public (undocumented) -export const colorPaletteNavyBorderActive: CSSDesignToken; +export const colorPaletteNavyBorderActive = "--colorPaletteNavyBorderActive"; // @public (undocumented) -export const colorPaletteNavyForeground2: CSSDesignToken; +export const colorPaletteNavyForeground2 = "--colorPaletteNavyForeground2"; // @public (undocumented) -export const colorPalettePeachBackground2: CSSDesignToken; +export const colorPalettePeachBackground2 = "--colorPalettePeachBackground2"; // @public (undocumented) -export const colorPalettePeachBorderActive: CSSDesignToken; +export const colorPalettePeachBorderActive = "--colorPalettePeachBorderActive"; // @public (undocumented) -export const colorPalettePeachForeground2: CSSDesignToken; +export const colorPalettePeachForeground2 = "--colorPalettePeachForeground2"; // @public (undocumented) -export const colorPalettePinkBackground2: CSSDesignToken; +export const colorPalettePinkBackground2 = "--colorPalettePinkBackground2"; // @public (undocumented) -export const colorPalettePinkBorderActive: CSSDesignToken; +export const colorPalettePinkBorderActive = "--colorPalettePinkBorderActive"; // @public (undocumented) -export const colorPalettePinkForeground2: CSSDesignToken; +export const colorPalettePinkForeground2 = "--colorPalettePinkForeground2"; // @public (undocumented) -export const colorPalettePlatinumBackground2: CSSDesignToken; +export const colorPalettePlatinumBackground2 = "--colorPalettePlatinumBackground2"; // @public (undocumented) -export const colorPalettePlatinumBorderActive: CSSDesignToken; +export const colorPalettePlatinumBorderActive = "--colorPalettePlatinumBorderActive"; // @public (undocumented) -export const colorPalettePlatinumForeground2: CSSDesignToken; +export const colorPalettePlatinumForeground2 = "--colorPalettePlatinumForeground2"; // @public (undocumented) -export const colorPalettePlumBackground2: CSSDesignToken; +export const colorPalettePlumBackground2 = "--colorPalettePlumBackground2"; // @public (undocumented) -export const colorPalettePlumBorderActive: CSSDesignToken; +export const colorPalettePlumBorderActive = "--colorPalettePlumBorderActive"; // @public (undocumented) -export const colorPalettePlumForeground2: CSSDesignToken; +export const colorPalettePlumForeground2 = "--colorPalettePlumForeground2"; // @public (undocumented) -export const colorPalettePumpkinBackground2: CSSDesignToken; +export const colorPalettePumpkinBackground2 = "--colorPalettePumpkinBackground2"; // @public (undocumented) -export const colorPalettePumpkinBorderActive: CSSDesignToken; +export const colorPalettePumpkinBorderActive = "--colorPalettePumpkinBorderActive"; // @public (undocumented) -export const colorPalettePumpkinForeground2: CSSDesignToken; +export const colorPalettePumpkinForeground2 = "--colorPalettePumpkinForeground2"; // @public (undocumented) -export const colorPalettePurpleBackground2: CSSDesignToken; +export const colorPalettePurpleBackground2 = "--colorPalettePurpleBackground2"; // @public (undocumented) -export const colorPalettePurpleBorderActive: CSSDesignToken; +export const colorPalettePurpleBorderActive = "--colorPalettePurpleBorderActive"; // @public (undocumented) -export const colorPalettePurpleForeground2: CSSDesignToken; +export const colorPalettePurpleForeground2 = "--colorPalettePurpleForeground2"; // @public (undocumented) -export const colorPaletteRedBackground1: CSSDesignToken; +export const colorPaletteRedBackground1 = "--colorPaletteRedBackground1"; // @public (undocumented) -export const colorPaletteRedBackground2: CSSDesignToken; +export const colorPaletteRedBackground2 = "--colorPaletteRedBackground2"; // @public (undocumented) -export const colorPaletteRedBackground3: CSSDesignToken; +export const colorPaletteRedBackground3 = "--colorPaletteRedBackground3"; // @public (undocumented) -export const colorPaletteRedBorder1: CSSDesignToken; +export const colorPaletteRedBorder1 = "--colorPaletteRedBorder1"; // @public (undocumented) -export const colorPaletteRedBorder2: CSSDesignToken; +export const colorPaletteRedBorder2 = "--colorPaletteRedBorder2"; // @public (undocumented) -export const colorPaletteRedBorderActive: CSSDesignToken; +export const colorPaletteRedBorderActive = "--colorPaletteRedBorderActive"; // @public (undocumented) -export const colorPaletteRedForeground1: CSSDesignToken; +export const colorPaletteRedForeground1 = "--colorPaletteRedForeground1"; // @public (undocumented) -export const colorPaletteRedForeground2: CSSDesignToken; +export const colorPaletteRedForeground2 = "--colorPaletteRedForeground2"; // @public (undocumented) -export const colorPaletteRedForeground3: CSSDesignToken; +export const colorPaletteRedForeground3 = "--colorPaletteRedForeground3"; // @public (undocumented) -export const colorPaletteRedForegroundInverted: CSSDesignToken; +export const colorPaletteRedForegroundInverted = "--colorPaletteRedForegroundInverted"; // @public (undocumented) -export const colorPaletteRoyalBlueBackground2: CSSDesignToken; +export const colorPaletteRoyalBlueBackground2 = "--colorPaletteRoyalBlueBackground2"; // @public (undocumented) -export const colorPaletteRoyalBlueBorderActive: CSSDesignToken; +export const colorPaletteRoyalBlueBorderActive = "--colorPaletteRoyalBlueBorderActive"; // @public (undocumented) -export const colorPaletteRoyalBlueForeground2: CSSDesignToken; +export const colorPaletteRoyalBlueForeground2 = "--colorPaletteRoyalBlueForeground2"; // @public (undocumented) -export const colorPaletteSeafoamBackground2: CSSDesignToken; +export const colorPaletteSeafoamBackground2 = "--colorPaletteSeafoamBackground2"; // @public (undocumented) -export const colorPaletteSeafoamBorderActive: CSSDesignToken; +export const colorPaletteSeafoamBorderActive = "--colorPaletteSeafoamBorderActive"; // @public (undocumented) -export const colorPaletteSeafoamForeground2: CSSDesignToken; +export const colorPaletteSeafoamForeground2 = "--colorPaletteSeafoamForeground2"; // @public (undocumented) -export const colorPaletteSteelBackground2: CSSDesignToken; +export const colorPaletteSteelBackground2 = "--colorPaletteSteelBackground2"; // @public (undocumented) -export const colorPaletteSteelBorderActive: CSSDesignToken; +export const colorPaletteSteelBorderActive = "--colorPaletteSteelBorderActive"; // @public (undocumented) -export const colorPaletteSteelForeground2: CSSDesignToken; +export const colorPaletteSteelForeground2 = "--colorPaletteSteelForeground2"; // @public (undocumented) -export const colorPaletteTealBackground2: CSSDesignToken; +export const colorPaletteTealBackground2 = "--colorPaletteTealBackground2"; // @public (undocumented) -export const colorPaletteTealBorderActive: CSSDesignToken; +export const colorPaletteTealBorderActive = "--colorPaletteTealBorderActive"; // @public (undocumented) -export const colorPaletteTealForeground2: CSSDesignToken; +export const colorPaletteTealForeground2 = "--colorPaletteTealForeground2"; // @public (undocumented) -export const colorPaletteYellowBackground1: CSSDesignToken; +export const colorPaletteYellowBackground1 = "--colorPaletteYellowBackground1"; // @public (undocumented) -export const colorPaletteYellowBackground2: CSSDesignToken; +export const colorPaletteYellowBackground2 = "--colorPaletteYellowBackground2"; // @public (undocumented) -export const colorPaletteYellowBackground3: CSSDesignToken; +export const colorPaletteYellowBackground3 = "--colorPaletteYellowBackground3"; // @public (undocumented) -export const colorPaletteYellowBorder1: CSSDesignToken; +export const colorPaletteYellowBorder1 = "--colorPaletteYellowBorder1"; // @public (undocumented) -export const colorPaletteYellowBorder2: CSSDesignToken; +export const colorPaletteYellowBorder2 = "--colorPaletteYellowBorder2"; // @public (undocumented) -export const colorPaletteYellowBorderActive: CSSDesignToken; +export const colorPaletteYellowBorderActive = "--colorPaletteYellowBorderActive"; // @public (undocumented) -export const colorPaletteYellowForeground1: CSSDesignToken; +export const colorPaletteYellowForeground1 = "--colorPaletteYellowForeground1"; // @public (undocumented) -export const colorPaletteYellowForeground2: CSSDesignToken; +export const colorPaletteYellowForeground2 = "--colorPaletteYellowForeground2"; // @public (undocumented) -export const colorPaletteYellowForeground3: CSSDesignToken; +export const colorPaletteYellowForeground3 = "--colorPaletteYellowForeground3"; // @public (undocumented) -export const colorPaletteYellowForegroundInverted: CSSDesignToken; +export const colorPaletteYellowForegroundInverted = "--colorPaletteYellowForegroundInverted"; // @public (undocumented) -export const colorScrollbarOverlay: CSSDesignToken; +export const colorScrollbarOverlay = "--colorScrollbarOverlay"; // @public (undocumented) -export const colorStrokeFocus1: CSSDesignToken; +export const colorStrokeFocus1 = "--colorStrokeFocus1"; // @public (undocumented) -export const colorStrokeFocus2: CSSDesignToken; +export const colorStrokeFocus2 = "--colorStrokeFocus2"; // @public (undocumented) -export const colorSubtleBackground: CSSDesignToken; +export const colorSubtleBackground = "--colorSubtleBackground"; // @public (undocumented) -export const colorSubtleBackgroundHover: CSSDesignToken; +export const colorSubtleBackgroundHover = "--colorSubtleBackgroundHover"; // @public (undocumented) -export const colorSubtleBackgroundInverted: CSSDesignToken; +export const colorSubtleBackgroundInverted = "--colorSubtleBackgroundInverted"; // @public (undocumented) -export const colorSubtleBackgroundInvertedHover: CSSDesignToken; +export const colorSubtleBackgroundInvertedHover = "--colorSubtleBackgroundInvertedHover"; // @public (undocumented) -export const colorSubtleBackgroundInvertedPressed: CSSDesignToken; +export const colorSubtleBackgroundInvertedPressed = "--colorSubtleBackgroundInvertedPressed"; // @public (undocumented) -export const colorSubtleBackgroundInvertedSelected: CSSDesignToken; +export const colorSubtleBackgroundInvertedSelected = "--colorSubtleBackgroundInvertedSelected"; // @public (undocumented) -export const colorSubtleBackgroundLightAlphaHover: CSSDesignToken; +export const colorSubtleBackgroundLightAlphaHover = "--colorSubtleBackgroundLightAlphaHover"; // @public (undocumented) -export const colorSubtleBackgroundLightAlphaPressed: CSSDesignToken; +export const colorSubtleBackgroundLightAlphaPressed = "--colorSubtleBackgroundLightAlphaPressed"; // @public (undocumented) -export const colorSubtleBackgroundLightAlphaSelected: CSSDesignToken; +export const colorSubtleBackgroundLightAlphaSelected = "--colorSubtleBackgroundLightAlphaSelected"; // @public (undocumented) -export const colorSubtleBackgroundPressed: CSSDesignToken; +export const colorSubtleBackgroundPressed = "--colorSubtleBackgroundPressed"; // @public (undocumented) -export const colorSubtleBackgroundSelected: CSSDesignToken; +export const colorSubtleBackgroundSelected = "--colorSubtleBackgroundSelected"; // @public (undocumented) -export const colorTransparentBackground: CSSDesignToken; +export const colorTransparentBackground = "--colorTransparentBackground"; // @public (undocumented) -export const colorTransparentBackgroundHover: CSSDesignToken; +export const colorTransparentBackgroundHover = "--colorTransparentBackgroundHover"; // @public (undocumented) -export const colorTransparentBackgroundPressed: CSSDesignToken; +export const colorTransparentBackgroundPressed = "--colorTransparentBackgroundPressed"; // @public (undocumented) -export const colorTransparentBackgroundSelected: CSSDesignToken; +export const colorTransparentBackgroundSelected = "--colorTransparentBackgroundSelected"; // @public (undocumented) -export const colorTransparentStroke: CSSDesignToken; +export const colorTransparentStroke = "--colorTransparentStroke"; // @public (undocumented) -export const colorTransparentStrokeDisabled: CSSDesignToken; +export const colorTransparentStrokeDisabled = "--colorTransparentStrokeDisabled"; // @public (undocumented) -export const colorTransparentStrokeInteractive: CSSDesignToken; +export const colorTransparentStrokeInteractive = "--colorTransparentStrokeInteractive"; // @public export class CompoundButton extends Button { @@ -1529,31 +1528,64 @@ export const CounterBadgeStyles: ElementStyles; export const CounterBadgeTemplate: ElementViewTemplate; // @public (undocumented) -export const curveAccelerateMax: CSSDesignToken; +export const curveAccelerateMax = "--curveAccelerateMax"; // @public (undocumented) -export const curveAccelerateMid: CSSDesignToken; +export const curveAccelerateMid = "--curveAccelerateMid"; // @public (undocumented) -export const curveAccelerateMin: CSSDesignToken; +export const curveAccelerateMin = "--curveAccelerateMin"; // @public (undocumented) -export const curveDecelerateMax: CSSDesignToken; +export const curveDecelerateMax = "--curveDecelerateMax"; // @public (undocumented) -export const curveDecelerateMid: CSSDesignToken; +export const curveDecelerateMid = "--curveDecelerateMid"; // @public (undocumented) -export const curveDecelerateMin: CSSDesignToken; +export const curveDecelerateMin = "--curveDecelerateMin"; // @public (undocumented) -export const curveEasyEase: CSSDesignToken; +export const curveEasyEase = "--curveEasyEase"; // @public (undocumented) -export const curveEasyEaseMax: CSSDesignToken; +export const curveEasyEaseMax = "--curveEasyEaseMax"; // @public (undocumented) -export const curveLinear: CSSDesignToken; +export const curveLinear = "--curveLinear"; + +// @public +export class Dialog extends FASTElement { + ariaDescribedby?: string; + ariaLabelledby?: string; + connectedCallback(): void; + defaultTitleAction?: Button; + dialog: HTMLDialogElement; + disconnectedCallback(): void; + dismiss(): void; + handleClick(event: Event): boolean; + handleKeydown: (e: KeyboardEvent) => boolean | void; + hide(dismissed?: boolean): void; + // Warning: (ae-forgotten-export) The symbol "DialogModalType" needs to be exported by the entry point index.d.ts + modalType: DialogModalType; + modalTypeChanged(oldValue: DialogModalType, newValue: DialogModalType): void; + noTitleAction: boolean; + onOpenChangeEvent: (dismissed?: boolean) => void; + open: boolean; + openChanged(oldValue: boolean, newValue: boolean): void; + setComponent(): void; + show(): void; + titleAction: HTMLElement[]; +} + +// @public +export const DialogDefinition: FASTElementDefinition; + +// @public +export const DialogStyles: ElementStyles; + +// @public +export const DialogTemplate: ElementViewTemplate; // @public export class Divider extends FASTDivider { @@ -1597,25 +1629,25 @@ export const DividerStyles: ElementStyles; export const DividerTemplate: ElementViewTemplate; // @public (undocumented) -export const durationFast: CSSDesignToken; +export const durationFast = "--durationFast"; // @public (undocumented) -export const durationFaster: CSSDesignToken; +export const durationFaster = "--durationFaster"; // @public (undocumented) -export const durationNormal: CSSDesignToken; +export const durationNormal = "--durationNormal"; // @public (undocumented) -export const durationSlow: CSSDesignToken; +export const durationSlow = "--durationSlow"; // @public (undocumented) -export const durationSlower: CSSDesignToken; +export const durationSlower = "--durationSlower"; // @public (undocumented) -export const durationUltraFast: CSSDesignToken; +export const durationUltraFast = "--durationUltraFast"; // @public (undocumented) -export const durationUltraSlow: CSSDesignToken; +export const durationUltraSlow = "--durationUltraSlow"; // @public (undocumented) export const FluentDesignSystem: Readonly<{ @@ -1625,55 +1657,55 @@ export const FluentDesignSystem: Readonly<{ }>; // @public (undocumented) -export const fontFamilyBase: CSSDesignToken; +export const fontFamilyBase = "--fontFamilyBase"; // @public (undocumented) -export const fontFamilyMonospace: CSSDesignToken; +export const fontFamilyMonospace = "--fontFamilyMonospace"; // @public (undocumented) -export const fontFamilyNumeric: CSSDesignToken; +export const fontFamilyNumeric = "--fontFamilyNumeric"; // @public (undocumented) -export const fontSizeBase100: CSSDesignToken; +export const fontSizeBase100 = "--fontSizeBase100"; // @public (undocumented) -export const fontSizeBase200: CSSDesignToken; +export const fontSizeBase200 = "--fontSizeBase200"; // @public (undocumented) -export const fontSizeBase300: CSSDesignToken; +export const fontSizeBase300 = "--fontSizeBase300"; // @public (undocumented) -export const fontSizeBase400: CSSDesignToken; +export const fontSizeBase400 = "--fontSizeBase400"; // @public (undocumented) -export const fontSizeBase500: CSSDesignToken; +export const fontSizeBase500 = "--fontSizeBase500"; // @public (undocumented) -export const fontSizeBase600: CSSDesignToken; +export const fontSizeBase600 = "--fontSizeBase600"; // @public (undocumented) -export const fontSizeHero1000: CSSDesignToken; +export const fontSizeHero1000 = "--fontSizeHero1000"; // @public (undocumented) -export const fontSizeHero700: CSSDesignToken; +export const fontSizeHero700 = "--fontSizeHero700"; // @public (undocumented) -export const fontSizeHero800: CSSDesignToken; +export const fontSizeHero800 = "--fontSizeHero800"; // @public (undocumented) -export const fontSizeHero900: CSSDesignToken; +export const fontSizeHero900 = "--fontSizeHero900"; // @public (undocumented) -export const fontWeightBold: CSSDesignToken; +export const fontWeightBold = "--fontWeightBold"; // @public (undocumented) -export const fontWeightMedium: CSSDesignToken; +export const fontWeightMedium = "--fontWeightMedium"; // @public (undocumented) -export const fontWeightRegular: CSSDesignToken; +export const fontWeightRegular = "--fontWeightRegular"; // @public (undocumented) -export const fontWeightSemibold: CSSDesignToken; +export const fontWeightSemibold = "--fontWeightSemibold"; // @public class Image_2 extends FASTElement { @@ -1736,34 +1768,65 @@ export const LabelStyles: ElementStyles; export const LabelTemplate: ElementViewTemplate
`; diff --git a/packages/web-components/src/toggle-button/toggle-button.styles.ts b/packages/web-components/src/toggle-button/toggle-button.styles.ts index 2de84d4416a84..a7501465ebcf9 100644 --- a/packages/web-components/src/toggle-button/toggle-button.styles.ts +++ b/packages/web-components/src/toggle-button/toggle-button.styles.ts @@ -33,78 +33,78 @@ export const styles = css` ${ButtonStyles} :host([aria-pressed="true"]) .control { - border-color: ${colorNeutralStroke1}; - background-color: ${colorNeutralBackground1Selected}; - color: ${colorNeutralForeground1}; - border-width: ${strokeWidthThin}; + border-color: var(${colorNeutralStroke1}); + background-color: var(${colorNeutralBackground1Selected}); + color: var(${colorNeutralForeground1}); + border-width: var(${strokeWidthThin}); } :host([aria-pressed='true']:hover) .control { - border-color: ${colorNeutralStroke1Hover}; - background-color: ${colorNeutralBackground1Hover}; + border-color: var(${colorNeutralStroke1Hover}); + background-color: var(${colorNeutralBackground1Hover}); } :host([aria-pressed='true']:active) .control { - border-color: ${colorNeutralStroke1Pressed}; - background-color: ${colorNeutralBackground1Pressed}; + border-color: var(${colorNeutralStroke1Pressed}); + background-color: var(${colorNeutralBackground1Pressed}); } :host([aria-pressed='true'][appearance='primary']) .control { border-color: transparent; - background-color: ${colorBrandBackgroundSelected}; - color: ${colorNeutralForegroundOnBrand}; + background-color: var(${colorBrandBackgroundSelected}); + color: var(${colorNeutralForegroundOnBrand}); } :host([aria-pressed='true'][appearance='primary']:hover) .control { - background-color: ${colorBrandBackgroundHover}; + background-color: var(${colorBrandBackgroundHover}); } :host([aria-pressed='true'][appearance='primary']:active) .control { - background-color: ${colorBrandBackgroundPressed}; + background-color: var(${colorBrandBackgroundPressed}); } :host([aria-pressed='true'][appearance='subtle']) .control { border-color: transparent; - background-color: ${colorSubtleBackgroundSelected}; - color: ${colorNeutralForeground2Selected}; + background-color: var(${colorSubtleBackgroundSelected}); + color: var(${colorNeutralForeground2Selected}); } :host([aria-pressed='true'][appearance='subtle']:hover) .control { - background-color: ${colorSubtleBackgroundHover}; - color: ${colorNeutralForeground2Hover}; + background-color: var(${colorSubtleBackgroundHover}); + color: var(${colorNeutralForeground2Hover}); } :host([aria-pressed='true'][appearance='subtle']:active) .control { - background-color: ${colorSubtleBackgroundPressed}; - color: ${colorNeutralForeground2Pressed}; + background-color: var(${colorSubtleBackgroundPressed}); + color: var(${colorNeutralForeground2Pressed}); } :host([aria-pressed='true'][appearance='outline']) .control, :host([aria-pressed='true'][appearance='transparent']) .control { - background-color: ${colorTransparentBackgroundSelected}; + background-color: var(${colorTransparentBackgroundSelected}); } :host([aria-pressed='true'][appearance='outline']:hover) .control, :host([aria-pressed='true'][appearance='transparent']:hover) .control { - background-color: ${colorTransparentBackgroundHover}; + background-color: var(${colorTransparentBackgroundHover}); } :host([aria-pressed='true'][appearance='outline']:active) .control, :host([aria-pressed='true'][appearance='transparent']:active) .control { - background-color: ${colorTransparentBackgroundPressed}; + background-color: var(${colorTransparentBackgroundPressed}); } :host([aria-pressed='true'][appearance='transparent']) .control { border-color: transparent; - color: ${colorNeutralForeground2BrandSelected}; + color: var(${colorNeutralForeground2BrandSelected}); } :host([aria-pressed='true'][appearance='transparent']:hover) .control { - color: ${colorNeutralForeground2BrandHover}; + color: var(${colorNeutralForeground2BrandHover}); } :host([aria-pressed='true'][appearance='transparent']:active) .control { - color: ${colorNeutralForeground2BrandPressed}; + color: var(${colorNeutralForeground2BrandPressed}); } `.withBehaviors( forcedColorsStylesheetBehavior(css` From 0c50929e3f99f9e952c9af39c6855efeb2455f04 Mon Sep 17 00:00:00 2001 From: Fluent UI Build Date: Fri, 9 Feb 2024 04:08:47 +0000 Subject: [PATCH 174/203] applying package updates --- apps/vr-tests-web-components/package.json | 2 +- ...ents-258db20e-84e5-451e-a289-97726ba08b24.json | 7 ------- packages/web-components/CHANGELOG.json | 15 +++++++++++++++ packages/web-components/CHANGELOG.md | 11 ++++++++++- packages/web-components/package.json | 2 +- 5 files changed, 27 insertions(+), 10 deletions(-) delete mode 100644 change/@fluentui-web-components-258db20e-84e5-451e-a289-97726ba08b24.json diff --git a/apps/vr-tests-web-components/package.json b/apps/vr-tests-web-components/package.json index a5b04fb6f8652..9c1ddd4f32a11 100644 --- a/apps/vr-tests-web-components/package.json +++ b/apps/vr-tests-web-components/package.json @@ -23,7 +23,7 @@ "dependencies": { "@fluentui/react-button": "^9.2.3", "@fluentui/react-storybook-addon": "*", - "@fluentui/web-components": "3.0.0-beta.6", + "@fluentui/web-components": "3.0.0-beta.7", "tslib": "^2.1.0" } } diff --git a/change/@fluentui-web-components-258db20e-84e5-451e-a289-97726ba08b24.json b/change/@fluentui-web-components-258db20e-84e5-451e-a289-97726ba08b24.json deleted file mode 100644 index 2fde1657e7630..0000000000000 --- a/change/@fluentui-web-components-258db20e-84e5-451e-a289-97726ba08b24.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "feat: remove JS design token implementation in favor of platform css variables", - "packageName": "@fluentui/web-components", - "email": "chhol@microsoft.com", - "dependentChangeType": "patch" -} diff --git a/packages/web-components/CHANGELOG.json b/packages/web-components/CHANGELOG.json index 5bbdeb3f0935a..def045b67f30b 100644 --- a/packages/web-components/CHANGELOG.json +++ b/packages/web-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/web-components", "entries": [ + { + "date": "Fri, 09 Feb 2024 04:08:43 GMT", + "tag": "@fluentui/web-components_v3.0.0-beta.7", + "version": "3.0.0-beta.7", + "comments": { + "prerelease": [ + { + "author": "chhol@microsoft.com", + "package": "@fluentui/web-components", + "commit": "4909fe2c8e9fb9029b5e7fa4d5aa73d299cf089f", + "comment": "feat: remove JS design token implementation in favor of platform css variables" + } + ] + } + }, { "date": "Fri, 01 Dec 2023 04:08:50 GMT", "tag": "@fluentui/web-components_v3.0.0-beta.6", diff --git a/packages/web-components/CHANGELOG.md b/packages/web-components/CHANGELOG.md index aa13f3ed6887c..80580ddd088d9 100644 --- a/packages/web-components/CHANGELOG.md +++ b/packages/web-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/web-components -This log was last generated on Thu, 26 Oct 2023 04:16:51 GMT and should not be manually modified. +This log was last generated on Fri, 09 Feb 2024 04:08:43 GMT and should not be manually modified. +## [3.0.0-beta.7](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-beta.7) + +Fri, 09 Feb 2024 04:08:43 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/web-components_v3.0.0-beta.6..@fluentui/web-components_v3.0.0-beta.7) + +### Changes + +- feat: remove JS design token implementation in favor of platform css variables ([PR #30002](https://github.com/microsoft/fluentui/pull/30002) by chhol@microsoft.com) + ## [3.0.0-beta.6](https://github.com/microsoft/fluentui/tree/@fluentui/web-components_v3.0.0-beta.6) Thu, 26 Oct 2023 04:16:51 GMT diff --git a/packages/web-components/package.json b/packages/web-components/package.json index d4aaffb01b9d0..155b104f554cc 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -1,7 +1,7 @@ { "name": "@fluentui/web-components", "description": "A library of Fluent Web Components", - "version": "3.0.0-beta.6", + "version": "3.0.0-beta.7", "author": { "name": "Microsoft", "url": "https://discord.gg/FcSNfg4" From 29de8268b978cd4e019ecff21ab53264cf5a851d Mon Sep 17 00:00:00 2001 From: Jeff Smith <37851214+eljefe223@users.noreply.github.com> Date: Thu, 8 Feb 2024 20:15:53 -0800 Subject: [PATCH 175/203] feat: removes dependency on fast-foundation templates and classes. (#30090) --- ...-b0669382-c509-4801-bd44-9849e8570a92.json | 7 + packages/web-components/docs/api-report.md | 685 +++++++++++++--- .../accordion-item.definition.ts | 3 - .../accordion-item/accordion-item.options.ts | 2 +- .../accordion-item/accordion-item.template.ts | 54 +- .../src/accordion-item/accordion-item.ts | 107 ++- .../src/accordion/accordion.definition.ts | 4 - .../src/accordion/accordion.options.ts | 16 + .../src/accordion/accordion.template.ts | 14 +- .../web-components/src/accordion/accordion.ts | 248 +++++- .../anchor-button/anchor-button.definition.ts | 3 - .../anchor-button/anchor-button.options.ts | 23 +- .../anchor-button/anchor-button.template.ts | 54 +- .../src/anchor-button/anchor-button.ts | 153 +++- .../src/avatar/avatar.options.ts | 2 +- .../src/badge/badge.definition.ts | 3 - .../web-components/src/badge/badge.options.ts | 4 +- .../src/badge/badge.template.ts | 4 +- packages/web-components/src/badge/badge.ts | 2 +- .../src/button/button.definition.ts | 3 - .../src/button/button.form-associated.ts | 13 + .../src/button/button.options.ts | 29 +- .../src/button/button.template.ts | 53 +- packages/web-components/src/button/button.ts | 231 +++++- .../src/checkbox/checkbox.form-associated.ts | 13 + .../src/checkbox/checkbox.options.ts | 2 +- .../src/checkbox/checkbox.template.ts | 46 +- .../web-components/src/checkbox/checkbox.ts | 84 +- .../compound-button.definition.ts | 3 - .../compound-button.options.ts | 4 +- .../compound-button.template.ts | 2 +- .../counter-badge/counter-badge.definition.ts | 4 - .../counter-badge/counter-badge.options.ts | 2 +- .../src/counter-badge/counter-badge.ts | 2 +- .../src/dialog/dialog.options.ts | 2 +- .../src/divider/divider.options.ts | 34 +- .../src/divider/divider.template.ts | 15 +- .../web-components/src/divider/divider.ts | 29 +- .../src/form-associated/form-associated.ts | 757 ++++++++++++++++++ .../web-components/src/image/image.options.ts | 2 +- .../web-components/src/label/label.options.ts | 2 +- .../src/menu-button/menu-button.definition.ts | 3 - .../src/menu-button/menu-button.options.ts | 4 +- .../src/menu-button/menu-button.template.ts | 2 +- .../src/menu-item/menu-item.definition.ts | 4 - .../src/menu-item/menu-item.options.ts | 39 + .../src/menu-item/menu-item.template.ts | 71 +- .../web-components/src/menu-item/menu-item.ts | 360 ++++++++- .../src/menu-list/menu-list.definition.ts | 4 - .../src/menu-list/menu-list.template.ts | 16 +- .../web-components/src/menu-list/menu-list.ts | 316 +++++++- .../src/patterns/aria-globals.ts | 230 ++++++ packages/web-components/src/patterns/index.ts | 2 + .../web-components/src/patterns/start-end.ts | 62 ++ .../src/progress-bar/base-progress.ts | 71 ++ .../src/progress-bar/progress-bar.options.ts | 12 +- .../src/progress-bar/progress-bar.template.ts | 32 +- .../src/progress-bar/progress-bar.ts | 15 +- .../progress-ring/progress-ring.options.ts | 10 + .../src/progress-ring/progress-ring.ts | 15 + .../web-components/src/radio-group/index.ts | 1 - .../src/radio-group/radio-group.options.ts | 14 + .../src/radio-group/radio-group.stories.ts | 2 +- .../src/radio-group/radio-group.template.ts | 33 +- .../src/radio-group/radio-group.ts | 414 +++++++++- .../src/radio/radio.form-associated.ts | 13 + .../src/radio/radio.template.ts | 33 +- packages/web-components/src/radio/radio.ts | 121 ++- .../src/slider/slider-utilities.ts | 17 + .../src/slider/slider.form-associated.ts | 13 + .../src/slider/slider.options.ts | 49 +- .../src/slider/slider.template.ts | 44 +- packages/web-components/src/slider/slider.ts | 526 +++++++++++- .../src/spinner/spinner.definition.ts | 4 - .../src/spinner/spinner.options.ts | 2 +- .../src/spinner/spinner.template.ts | 35 +- .../web-components/src/spinner/spinner.ts | 4 +- .../src/switch/switch.form-associated.ts | 13 + .../src/switch/switch.options.ts | 2 +- .../src/switch/switch.template.ts | 30 +- packages/web-components/src/switch/switch.ts | 71 +- .../src/tab-panel/tab-panel.template.ts | 11 +- .../web-components/src/tab-panel/tab-panel.ts | 4 +- .../web-components/src/tab/tab.template.ts | 6 +- packages/web-components/src/tab/tab.ts | 26 +- .../web-components/src/tabs/tabs.options.ts | 24 +- .../web-components/src/tabs/tabs.stories.ts | 3 +- .../web-components/src/tabs/tabs.template.ts | 18 +- packages/web-components/src/tabs/tabs.ts | 336 +++++++- .../web-components/src/text-input/index.ts | 1 - .../text-input/text-field.form-associated.ts | 13 + .../src/text-input/text-input.options.ts | 39 +- .../src/text-input/text-input.template.ts | 69 +- .../src/text-input/text-input.ts | 251 +++++- .../web-components/src/text/text.options.ts | 2 +- .../toggle-button/toggle-button.definition.ts | 2 - .../toggle-button/toggle-button.options.ts | 4 +- .../toggle-button/toggle-button.template.ts | 2 +- .../web-components/src/utils/direction.ts | 15 + packages/web-components/src/utils/index.ts | 4 + .../src/utils/template-helpers.ts | 40 + packages/web-components/src/utils/typings.ts | 8 + .../src/utils/whitespace-filter.ts | 16 + 103 files changed, 6007 insertions(+), 316 deletions(-) create mode 100644 change/@fluentui-web-components-b0669382-c509-4801-bd44-9849e8570a92.json create mode 100644 packages/web-components/src/accordion/accordion.options.ts create mode 100644 packages/web-components/src/button/button.form-associated.ts create mode 100644 packages/web-components/src/checkbox/checkbox.form-associated.ts create mode 100644 packages/web-components/src/form-associated/form-associated.ts create mode 100644 packages/web-components/src/menu-item/menu-item.options.ts create mode 100644 packages/web-components/src/patterns/aria-globals.ts create mode 100644 packages/web-components/src/patterns/index.ts create mode 100644 packages/web-components/src/patterns/start-end.ts create mode 100644 packages/web-components/src/progress-bar/base-progress.ts create mode 100644 packages/web-components/src/progress-ring/progress-ring.options.ts create mode 100644 packages/web-components/src/progress-ring/progress-ring.ts create mode 100644 packages/web-components/src/radio-group/radio-group.options.ts create mode 100644 packages/web-components/src/radio/radio.form-associated.ts create mode 100644 packages/web-components/src/slider/slider-utilities.ts create mode 100644 packages/web-components/src/slider/slider.form-associated.ts create mode 100644 packages/web-components/src/switch/switch.form-associated.ts create mode 100644 packages/web-components/src/text-input/text-field.form-associated.ts create mode 100644 packages/web-components/src/utils/direction.ts create mode 100644 packages/web-components/src/utils/index.ts create mode 100644 packages/web-components/src/utils/template-helpers.ts create mode 100644 packages/web-components/src/utils/typings.ts create mode 100644 packages/web-components/src/utils/whitespace-filter.ts diff --git a/change/@fluentui-web-components-b0669382-c509-4801-bd44-9849e8570a92.json b/change/@fluentui-web-components-b0669382-c509-4801-bd44-9849e8570a92.json new file mode 100644 index 0000000000000..77a57797f6f18 --- /dev/null +++ b/change/@fluentui-web-components-b0669382-c509-4801-bd44-9849e8570a92.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Removes dependancy on fast-foundation classes and templates", + "packageName": "@fluentui/web-components", + "email": "jes@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/docs/api-report.md b/packages/web-components/docs/api-report.md index 042a9ff09a728..2cf13edf679c0 100644 --- a/packages/web-components/docs/api-report.md +++ b/packages/web-components/docs/api-report.md @@ -4,65 +4,60 @@ ```ts -import type { AnchorOptions as AnchorButtonOptions } from '@microsoft/fast-foundation/anchor.js'; -import type { ButtonOptions } from '@microsoft/fast-foundation/button.js'; -import { DividerOrientation } from '@microsoft/fast-foundation/divider.js'; -import { DividerRole } from '@microsoft/fast-foundation/divider.js'; +import type { Constructable } from '@microsoft/fast-element'; +import { Direction } from '@microsoft/fast-web-utilities'; import { ElementStyles } from '@microsoft/fast-element'; import { ElementViewTemplate } from '@microsoft/fast-element'; -import { FASTAccordion } from '@microsoft/fast-foundation/accordion.js'; -import { FASTAccordionItem } from '@microsoft/fast-foundation/accordion-item.js'; -import { FASTAnchor } from '@microsoft/fast-foundation/anchor.js'; -import { FASTButton } from '@microsoft/fast-foundation/button.js'; -import { FASTCheckbox } from '@microsoft/fast-foundation/checkbox.js'; -import { FASTDivider } from '@microsoft/fast-foundation/divider.js'; import { FASTElement } from '@microsoft/fast-element'; import { FASTElementDefinition } from '@microsoft/fast-element'; -import { FASTMenu } from '@microsoft/fast-foundation/menu.js'; -import { FASTMenuItem } from '@microsoft/fast-foundation/menu-item.js'; -import { FASTProgress } from '@microsoft/fast-foundation/progress.js'; -import { FASTProgressRing } from '@microsoft/fast-foundation/progress-ring.js'; -import { FASTRadio } from '@microsoft/fast-foundation/radio.js'; -import { FASTRadioGroup } from '@microsoft/fast-foundation/radio-group.js'; -import { FASTSlider } from '@microsoft/fast-foundation/slider.js'; -import { FASTSwitch } from '@microsoft/fast-foundation/switch.js'; -import { FASTTab } from '@microsoft/fast-foundation/tab.js'; -import { FASTTabPanel } from '@microsoft/fast-foundation/tab-panel.js'; -import { FASTTabs } from '@microsoft/fast-foundation/tabs.js'; -import { FASTTextField } from '@microsoft/fast-foundation/text-field.js'; -import { MenuItemRole } from '@microsoft/fast-foundation/menu-item.js'; -import { RadioGroupOrientation } from '@microsoft/fast-foundation/radio-group.js'; -import { SliderOrientation } from '@microsoft/fast-foundation/slider.js'; -import { StartEnd } from '@microsoft/fast-foundation/patterns.js'; -import { StartEndOptions } from '@microsoft/fast-foundation/patterns.js'; -import type { StaticallyComposableHTML } from '@microsoft/fast-foundation/utilities.js'; -import { TabsOrientation } from '@microsoft/fast-foundation/tabs.js'; -import { TextFieldType as TextInputType } from '@microsoft/fast-foundation/text-field.js'; +import { HTMLDirective } from '@microsoft/fast-element'; +import { Orientation } from '@microsoft/fast-web-utilities'; +import type { SyntheticViewTemplate } from '@microsoft/fast-element'; import type { Theme } from '@fluentui/tokens'; -import type { ValuesOf } from '@microsoft/fast-foundation/utilities.js'; // @public -export class Accordion extends FASTAccordion { +export class Accordion extends FASTElement { + // (undocumented) + protected accordionItems: Element[]; + // Warning: (ae-forgotten-export) The symbol "AccordionExpandMode" needs to be exported by the entry point index.d.ts + expandmode: AccordionExpandMode; + // (undocumented) + expandmodeChanged(prev: AccordionExpandMode, next: AccordionExpandMode): void; + // @internal (undocumented) + handleChange(source: any, propertyName: string): void; + // @internal (undocumented) + slottedAccordionItems: HTMLElement[]; + // @internal (undocumented) + slottedAccordionItemsChanged(oldValue: HTMLElement[], newValue: HTMLElement[]): void; } -// @public +// @public (undocumented) export const accordionDefinition: FASTElementDefinition; -// Warning: (ae-internal-missing-underscore) The name "AccordionItem" should be prefixed with an underscore because the declaration is marked as @internal +// Warning: (ae-internal-mixed-release-tag) Mixed release tags are not allowed for "AccordionItem" because one of its declarations is marked as @internal // -// @internal (undocumented) -export class AccordionItem extends FASTAccordionItem { - // @public +// @public +export class AccordionItem extends FASTElement { block: boolean; - // @public + // @internal (undocumented) + clickHandler: (e: MouseEvent) => void; + disabled: boolean; + // @internal (undocumented) + expandbutton: HTMLElement; + expanded: boolean; expandIconPosition?: AccordionItemExpandIconPosition; - // @public + headinglevel: 1 | 2 | 3 | 4 | 5 | 6; + id: string; size?: AccordionItemSize; } -// Warning: (ae-incompatible-release-tags) The symbol "definition" is marked as @public, but its signature references "AccordionItem" which is marked as @internal +// Warning: (ae-forgotten-export) The symbol "StartEnd" needs to be exported by the entry point index.d.ts // -// @public +// @internal +export interface AccordionItem extends StartEnd { +} + +// @public (undocumented) export const accordionItemDefinition: FASTElementDefinition; // @public @@ -71,9 +66,19 @@ export const AccordionItemExpandIconPosition: { readonly end: "end"; }; +// Warning: (ae-forgotten-export) The symbol "ValuesOf" needs to be exported by the entry point index.d.ts +// // @public export type AccordionItemExpandIconPosition = ValuesOf; +// Warning: (ae-forgotten-export) The symbol "StartEndOptions" needs to be exported by the entry point index.d.ts +// +// @public +export type AccordionItemOptions = StartEndOptions & { + expandedIcon?: StaticallyComposableHTML; + collapsedIcon?: StaticallyComposableHTML; +}; + // @public export const AccordionItemSize: { readonly small: "small"; @@ -88,8 +93,6 @@ export type AccordionItemSize = ValuesOf; // @public (undocumented) export const accordionItemStyles: ElementStyles; -// Warning: (ae-incompatible-release-tags) The symbol "template" is marked as @public, but its signature references "AccordionItem" which is marked as @internal -// // @public export const accordionItemTemplate: ElementViewTemplate; @@ -99,11 +102,16 @@ export const accordionStyles: ElementStyles; // @public (undocumented) export const accordionTemplate: ElementViewTemplate; +// Warning: (ae-internal-mixed-release-tag) Mixed release tags are not allowed for "AnchorButton" because one of its declarations is marked as @internal +// // @public -export class AnchorButton extends FASTAnchor { +export class AnchorButton extends FASTElement { appearance?: AnchorButtonAppearance | undefined; // (undocumented) connectedCallback(): void; + control: HTMLAnchorElement; + // @internal + defaultSlottedContent: HTMLElement[]; disabled?: boolean; // (undocumented) protected disabledChanged(prev: boolean, next: boolean): void; @@ -112,9 +120,21 @@ export class AnchorButton extends FASTAnchor { protected disabledFocusableChanged(prev: boolean, next: boolean): void; // (undocumented) disconnectedCallback(): void; + download: string; + href: string; + hreflang: string; iconOnly: boolean; + ping: string; + referrerpolicy: string; + rel: string; shape?: AnchorButtonShape | undefined; size?: AnchorButtonSize; + target: AnchorTarget; + type: string; +} + +// @internal +export interface AnchorButton extends StartEnd, DelegatesARIALink { } // @public @@ -129,11 +149,9 @@ export const AnchorButtonAppearance: { // @public export type AnchorButtonAppearance = ValuesOf; -// @public +// @public (undocumented) export const AnchorButtonDefinition: FASTElementDefinition; -export { AnchorButtonOptions } - // @public export const AnchorButtonShape: { readonly circular: "circular"; @@ -157,6 +175,22 @@ export type AnchorButtonSize = ValuesOf; // @public export const AnchorButtonTemplate: ElementViewTemplate; +// @public +type AnchorOptions = StartEndOptions; +export { AnchorOptions as AnchorButtonOptions } +export { AnchorOptions } + +// @public +export const AnchorTarget: { + readonly _self: "_self"; + readonly _blank: "_blank"; + readonly _parent: "_parent"; + readonly _top: "_top"; +}; + +// @public +export type AnchorTarget = ValuesOf; + // @public export class Avatar extends FASTElement { active?: AvatarActive | undefined; @@ -349,7 +383,7 @@ export const BadgeColor: { // @public export type BadgeColor = ValuesOf; -// @public +// @public (undocumented) export const BadgeDefinition: FASTElementDefinition; // Warning: (ae-internal-missing-underscore) The name "BadgeOptions" should be prefixed with an underscore because the declaration is marked as @internal @@ -406,19 +440,53 @@ export const borderRadiusSmall = "--borderRadiusSmall"; // @public (undocumented) export const borderRadiusXLarge = "--borderRadiusXLarge"; +// Warning: (ae-forgotten-export) The symbol "FormAssociatedButton" needs to be exported by the entry point index.d.ts +// Warning: (ae-internal-mixed-release-tag) Mixed release tags are not allowed for "Button" because one of its declarations is marked as @internal +// // @public -export class Button extends FASTButton { +export class Button extends FormAssociatedButton { appearance?: ButtonAppearance | undefined; - // (undocumented) + autofocus: boolean; + // @internal (undocumented) connectedCallback(): void; + // (undocumented) + control: HTMLButtonElement; + defaultSlottedContent: HTMLElement[]; disabledFocusable?: boolean; // (undocumented) protected disabledFocusableChanged(prev: boolean, next: boolean): void; // (undocumented) disconnectedCallback(): void; + formaction: string; + // (undocumented) + protected formactionChanged(): void; + formenctype: string; + // (undocumented) + protected formenctypeChanged(): void; + formId: string; + formmethod: string; + // (undocumented) + protected formmethodChanged(): void; + formnovalidate: boolean; + // (undocumented) + protected formnovalidateChanged(): void; + formtarget: '_self' | '_blank' | '_parent' | '_top'; + // (undocumented) + protected formtargetChanged(): void; iconOnly: boolean; shape?: ButtonShape | undefined; size?: ButtonSize; + type: ButtonType; + // (undocumented) + protected typeChanged(previous: ButtonType | undefined, next: ButtonType): void; + // Warning: (ae-unresolved-inheritdoc-reference) The @inheritDoc reference could not be resolved: The package "@fluentui/web-components" does not have an export "FormAssociated" + // + // (undocumented) + validate(): void; +} + +// @internal +export interface Button extends StartEnd, DelegatesARIAButton { } // @public @@ -433,9 +501,11 @@ export const ButtonAppearance: { // @public export type ButtonAppearance = ValuesOf; -// @public +// @public (undocumented) export const ButtonDefinition: FASTElementDefinition; +// @public +type ButtonOptions = StartEndOptions + ${startSlotTemplate(options)} + ${endSlotTemplate(options)} +
+
+ +
+`; +} + /** * The template for the fluent-accordion component. * @public diff --git a/packages/web-components/src/accordion-item/accordion-item.ts b/packages/web-components/src/accordion-item/accordion-item.ts index 3ef3e4b104eee..0cb815af2f085 100644 --- a/packages/web-components/src/accordion-item/accordion-item.ts +++ b/packages/web-components/src/accordion-item/accordion-item.ts @@ -1,11 +1,84 @@ -import { attr } from '@microsoft/fast-element'; -import { FASTAccordionItem } from '@microsoft/fast-foundation/accordion-item.js'; +import { attr, FASTElement, nullableNumberConverter } from '@microsoft/fast-element'; +import { uniqueId } from '@microsoft/fast-web-utilities'; +import type { StaticallyComposableHTML } from '../utils/index.js'; +import { StartEnd } from '../patterns/index.js'; +import type { StartEndOptions } from '../patterns/index.js'; +import { applyMixins } from '../utils/apply-mixins.js'; import { AccordionItemExpandIconPosition, AccordionItemSize } from './accordion-item.options.js'; /** - * @internal + * Accordion Item configuration options + * @public + */ +export type AccordionItemOptions = StartEndOptions & { + expandedIcon?: StaticallyComposableHTML; + collapsedIcon?: StaticallyComposableHTML; +}; + +/** + * + * @slot start - Content which can be provided between the heading and the icon + * @slot end - Content which can be provided between the start slot and icon + * @slot heading - Content which serves as the accordion item heading and text of the expand button + * @slot - The default slot for accordion item content + * @slot expanded-icon - The expanded icon + * @slot collapsed-icon - The collapsed icon + * @fires change - Fires a custom 'change' event when the button is invoked + * @csspart heading - Wraps the button + * @csspart button - The button which serves to invoke the item + * @csspart heading-content - Wraps the slot for the heading content within the button + * @csspart icon - The icon container + * @csspart region - The wrapper for the accordion item content + * + * @public */ -export class AccordionItem extends FASTAccordionItem { +export class AccordionItem extends FASTElement { + /** + * Configures the {@link https://www.w3.org/TR/wai-aria-1.1/#aria-level | level} of the + * heading element. + * + * @defaultValue 2 + * @public + * @remarks + * HTML attribute: heading-level + */ + @attr({ + attribute: 'heading-level', + mode: 'fromView', + converter: nullableNumberConverter, + }) + public headinglevel: 1 | 2 | 3 | 4 | 5 | 6 = 2; + + /** + * Expands or collapses the item. + * + * @public + * @remarks + * HTML attribute: expanded + */ + @attr({ mode: 'boolean' }) + public expanded: boolean = false; + + /** + * Disables an accordion item + * + * @public + * @remarks + * HTML attribute: disabled + */ + @attr({ mode: 'boolean' }) + public disabled: boolean = false; + + /** + * The item ID + * + * @public + * @remarks + * HTML Attribute: id + */ + @attr + public id: string = uniqueId('accordion-'); + /** * Defines accordion header font size. * @@ -37,4 +110,30 @@ export class AccordionItem extends FASTAccordionItem { */ @attr({ attribute: 'expand-icon-position' }) public expandIconPosition?: AccordionItemExpandIconPosition; + + /** + * @internal + */ + public expandbutton!: HTMLElement; + + /** + * @internal + */ + public clickHandler = (e: MouseEvent) => { + if (this.disabled) { + return; + } + + this.$emit('click', e); + }; } + +/** + * Mark internal because exporting class and interface of the same name + * confuses API documenter. + * TODO: https://github.com/microsoft/fast/issues/3317 + * @internal + */ +/* eslint-disable-next-line @typescript-eslint/no-empty-interface */ +export interface AccordionItem extends StartEnd {} +applyMixins(AccordionItem, StartEnd); diff --git a/packages/web-components/src/accordion/accordion.definition.ts b/packages/web-components/src/accordion/accordion.definition.ts index aa47c704ae1a8..e8f3fc603ee36 100644 --- a/packages/web-components/src/accordion/accordion.definition.ts +++ b/packages/web-components/src/accordion/accordion.definition.ts @@ -4,10 +4,6 @@ import { styles } from './accordion.styles.js'; import { template } from './accordion.template.js'; /** - * The Fluent Accordion Element. Implements {@link @microsoft/fast-foundation#Accordion }, - * {@link @microsoft/fast-foundation#accordionTemplate} - * - * * @public * @remarks * HTML Element: \ diff --git a/packages/web-components/src/accordion/accordion.options.ts b/packages/web-components/src/accordion/accordion.options.ts new file mode 100644 index 0000000000000..0fc3656b44ca6 --- /dev/null +++ b/packages/web-components/src/accordion/accordion.options.ts @@ -0,0 +1,16 @@ +import type { ValuesOf } from '../utils/index.js'; + +/** + * Expand mode for {@link FASTAccordion} + * @public + */ +export const AccordionExpandMode = { + single: 'single', + multi: 'multi', +} as const; + +/** + * Type for the {@link FASTAccordion} Expand Mode + * @public + */ +export type AccordionExpandMode = ValuesOf; diff --git a/packages/web-components/src/accordion/accordion.template.ts b/packages/web-components/src/accordion/accordion.template.ts index bc7e767e698aa..2f181ac6c1456 100644 --- a/packages/web-components/src/accordion/accordion.template.ts +++ b/packages/web-components/src/accordion/accordion.template.ts @@ -1,5 +1,15 @@ -import { ElementViewTemplate } from '@microsoft/fast-element'; -import { accordionTemplate } from '@microsoft/fast-foundation/accordion.js'; +import { elements, ElementViewTemplate, html, slotted } from '@microsoft/fast-element'; import type { Accordion } from './accordion.js'; +/** + * @public + */ +export function accordionTemplate(): ElementViewTemplate { + return html` + + `; +} + export const template: ElementViewTemplate = accordionTemplate(); diff --git a/packages/web-components/src/accordion/accordion.ts b/packages/web-components/src/accordion/accordion.ts index 1541711123888..9de8a8c59cad7 100644 --- a/packages/web-components/src/accordion/accordion.ts +++ b/packages/web-components/src/accordion/accordion.ts @@ -1,7 +1,249 @@ -import { FASTAccordion } from '@microsoft/fast-foundation/accordion.js'; +import { Observable } from '@microsoft/fast-element'; +import { attr, FASTElement, observable } from '@microsoft/fast-element'; +import { keyArrowDown, keyArrowUp, keyEnd, keyHome, wrapInBounds } from '@microsoft/fast-web-utilities'; +import { AccordionItem } from '../accordion-item/accordion-item.js'; +import { AccordionExpandMode } from './accordion.options.js'; /** - * The base class used for constructing a fluent-accordion custom element + * An Accordion Custom HTML Element + * Implements {@link https://www.w3.org/TR/wai-aria-practices-1.1/#accordion | ARIA Accordion}. + * + * @fires change - Fires a custom 'change' event when the active item changes + * @csspart item - The slot for the accordion items * @public */ -export class Accordion extends FASTAccordion {} +export class Accordion extends FASTElement { + /** + * Controls the expand mode of the Accordion, either allowing + * single or multiple item expansion. + * @public + * + * @remarks + * HTML attribute: expand-mode + */ + @attr({ attribute: 'expand-mode' }) + public expandmode: AccordionExpandMode = AccordionExpandMode.multi; + public expandmodeChanged(prev: AccordionExpandMode, next: AccordionExpandMode) { + if (!this.$fastController.isConnected) { + return; + } + + const expandedItem = this.findExpandedItem(); + + if (!expandedItem) { + return; + } + + if (next !== AccordionExpandMode.single) { + (expandedItem as AccordionItem)?.expandbutton.removeAttribute('aria-disabled'); + } else { + this.setSingleExpandMode(expandedItem); + } + } + + /** + * @internal + */ + @observable + public slottedAccordionItems!: HTMLElement[]; + + protected accordionItems!: Element[]; + + /** + * @internal + */ + public slottedAccordionItemsChanged(oldValue: HTMLElement[], newValue: HTMLElement[]): void { + if (this.$fastController.isConnected) { + this.setItems(); + } + } + + /** + * @internal + */ + public handleChange(source: any, propertyName: string) { + if (propertyName === 'disabled') { + this.setItems(); + } else if (propertyName === 'expanded') { + // we only need to manage single expanded instances + // such as scenarios where a child is programatically expanded + if (source.expanded && this.isSingleExpandMode()) { + this.setSingleExpandMode(source); + } + } + } + + private activeid!: string | null; + private activeItemIndex: number = 0; + private accordionIds!: Array; + + private change = (): void => { + this.$emit('change', this.activeid); + }; + + private findExpandedItem(): AccordionItem | Element | null { + if (this.accordionItems.length === 0) { + return null; + } + + return ( + this.accordionItems.find((item: Element | AccordionItem) => item instanceof AccordionItem && item.expanded) ?? + this.accordionItems[0] + ); + } + + private setItems = (): void => { + if (this.slottedAccordionItems.length === 0) { + return; + } + + const children: Element[] = Array.from(this.children); + + this.removeItemListeners(children); + + children.forEach((child: Element) => Observable.getNotifier(child).subscribe(this, 'disabled')); + + this.accordionItems = children.filter(child => !child.hasAttribute('disabled')); + + this.accordionIds = this.getItemIds(); + + this.accordionItems.forEach((item: Element, index: number) => { + if (item instanceof AccordionItem) { + item.addEventListener('click', this.activeItemChange); + item.addEventListener('keydown', this.handleItemKeyDown); + item.addEventListener('focus', this.handleItemFocus); + Observable.getNotifier(item).subscribe(this, 'expanded'); + } + + const itemId: string | null = this.accordionIds[index]; + item.setAttribute('id', typeof itemId !== 'string' ? `accordion-${index + 1}` : itemId); + this.activeid = this.accordionIds[this.activeItemIndex] as string; + }); + + if (this.isSingleExpandMode()) { + const expandedItem = this.findExpandedItem() as AccordionItem; + this.setSingleExpandMode(expandedItem); + } + }; + + private setSingleExpandMode(expandedItem: Element): void { + if (this.accordionItems.length === 0) { + return; + } + const currentItems = Array.from(this.accordionItems); + this.activeItemIndex = currentItems.indexOf(expandedItem); + + currentItems.forEach((item: Element, index: number) => { + if (item instanceof AccordionItem) { + if (this.activeItemIndex === index) { + item.expanded = true; + item.expandbutton.setAttribute('aria-disabled', 'true'); + } else { + item.expanded = false; + + if (!item.hasAttribute('disabled')) { + item.expandbutton.removeAttribute('aria-disabled'); + } + } + } + }); + } + + private removeItemListeners = (oldValue: any): void => { + oldValue.forEach((item: HTMLElement, index: number) => { + Observable.getNotifier(item).unsubscribe(this, 'disabled'); + Observable.getNotifier(item).unsubscribe(this, 'expanded'); + item.removeEventListener('click', this.activeItemChange); + item.removeEventListener('keydown', this.handleItemKeyDown); + item.removeEventListener('focus', this.handleItemFocus); + }); + }; + + private activeItemChange = (event: Event): void => { + if (event.defaultPrevented || event.target !== event.currentTarget) { + return; + } + + event.preventDefault(); + + this.handleExpandedChange(event.target as HTMLElement); + }; + + private handleExpandedChange = (item: HTMLElement) => { + if (item instanceof AccordionItem) { + this.activeid = item.getAttribute('id'); + + if (!this.isSingleExpandMode()) { + item.expanded = !item.expanded; + // setSingleExpandMode sets activeItemIndex on its own + this.activeItemIndex = this.accordionItems.indexOf(item); + } else { + this.setSingleExpandMode(item); + } + + this.change(); + } + }; + + private getItemIds(): Array { + return this.slottedAccordionItems.map((accordionItem: HTMLElement) => { + return accordionItem.id; + }); + } + + private isSingleExpandMode(): boolean { + return this.expandmode === AccordionExpandMode.single; + } + + private handleItemKeyDown = (event: KeyboardEvent): void => { + // only handle the keydown if the event target is the accordion item + // prevents arrow keys from moving focus to accordion headers when focus is on accordion item panel content + if (event.target !== event.currentTarget) { + return; + } + this.accordionIds = this.getItemIds(); + switch (event.key) { + case keyArrowUp: + event.preventDefault(); + this.adjust(-1); + break; + case keyArrowDown: + event.preventDefault(); + this.adjust(1); + break; + case keyHome: + this.activeItemIndex = 0; + this.focusItem(); + break; + case keyEnd: + this.activeItemIndex = this.accordionItems.length - 1; + this.focusItem(); + break; + } + }; + + private handleItemFocus = (event: FocusEvent): void => { + // update the active item index if the focus moves to an accordion item via a different method other than the up and down arrow key actions + // only do so if the focus is actually on the accordion item and not on any of its children + if (event.target === event.currentTarget) { + const focusedItem = event.target as HTMLElement; + const focusedIndex: number = (this.activeItemIndex = Array.from(this.accordionItems).indexOf(focusedItem)); + if (this.activeItemIndex !== focusedIndex && focusedIndex !== -1) { + this.activeItemIndex = focusedIndex; + this.activeid = this.accordionIds[this.activeItemIndex] as string; + } + } + }; + + private adjust(adjustment: number): void { + this.activeItemIndex = wrapInBounds(0, this.accordionItems.length - 1, this.activeItemIndex + adjustment); + this.focusItem(); + } + + private focusItem(): void { + const element: Element = this.accordionItems[this.activeItemIndex]; + if (element instanceof AccordionItem) { + element.expandbutton.focus(); + } + } +} diff --git a/packages/web-components/src/anchor-button/anchor-button.definition.ts b/packages/web-components/src/anchor-button/anchor-button.definition.ts index 9a76a726216de..14f6561041e6c 100644 --- a/packages/web-components/src/anchor-button/anchor-button.definition.ts +++ b/packages/web-components/src/anchor-button/anchor-button.definition.ts @@ -4,9 +4,6 @@ import { styles } from './anchor-button.styles.js'; import { template } from './anchor-button.template.js'; /** - * The Fluent Anchor Button Element. Implements {@link @microsoft/fast-foundation#Anchor }, - * {@link @microsoft/fast-foundation#anchorTemplate} - * * @public * @remarks * HTML Element: \ diff --git a/packages/web-components/src/anchor-button/anchor-button.options.ts b/packages/web-components/src/anchor-button/anchor-button.options.ts index 43203acfd2b0d..12785a8ab21ee 100644 --- a/packages/web-components/src/anchor-button/anchor-button.options.ts +++ b/packages/web-components/src/anchor-button/anchor-button.options.ts @@ -1,6 +1,6 @@ -import type { AnchorOptions } from '@microsoft/fast-foundation/anchor.js'; -import type { ValuesOf } from '@microsoft/fast-foundation/utilities.js'; import { ButtonAppearance, ButtonShape, ButtonSize } from '../button/button.options.js'; +import type { ValuesOf } from '../utils/index.js'; +import type { AnchorOptions } from './anchor-button.js'; /** * Anchor Button Appearance constants @@ -39,3 +39,22 @@ export const AnchorButtonSize = ButtonSize; export type AnchorButtonSize = ValuesOf; export { AnchorOptions as AnchorButtonOptions }; + +/** + * Anchor target values. + * + * @public + */ +export const AnchorTarget = { + _self: '_self', + _blank: '_blank', + _parent: '_parent', + _top: '_top', +} as const; + +/** + * Type for anchor target values. + * + * @public + */ +export type AnchorTarget = ValuesOf; diff --git a/packages/web-components/src/anchor-button/anchor-button.template.ts b/packages/web-components/src/anchor-button/anchor-button.template.ts index abf13779af6d0..015315a8eaffa 100644 --- a/packages/web-components/src/anchor-button/anchor-button.template.ts +++ b/packages/web-components/src/anchor-button/anchor-button.template.ts @@ -1,6 +1,54 @@ -import { ElementViewTemplate } from '@microsoft/fast-element'; -import { anchorTemplate } from '@microsoft/fast-foundation/anchor.js'; -import type { AnchorButton } from './anchor-button.js'; +import { ElementViewTemplate, html, ref, slotted, ViewTemplate } from '@microsoft/fast-element'; +import { endSlotTemplate, startSlotTemplate } from '../patterns/index.js'; +import type { AnchorButton, AnchorOptions } from './anchor-button.js'; + +/** + * The template for the Button component. + * @public + */ +export function anchorTemplate(options: AnchorOptions = {}): ViewTemplate { + return html` + + ${startSlotTemplate(options)} + + + + ${endSlotTemplate(options)} + + `; +} /** * The template for the Button component. diff --git a/packages/web-components/src/anchor-button/anchor-button.ts b/packages/web-components/src/anchor-button/anchor-button.ts index 0fae967bbb699..68c09787c5e01 100644 --- a/packages/web-components/src/anchor-button/anchor-button.ts +++ b/packages/web-components/src/anchor-button/anchor-button.ts @@ -1,12 +1,119 @@ -import { attr } from '@microsoft/fast-element'; -import { FASTAnchor } from '@microsoft/fast-foundation/anchor.js'; -import { AnchorButtonAppearance, AnchorButtonShape, AnchorButtonSize } from './anchor-button.options.js'; +import { attr, FASTElement, observable } from '@microsoft/fast-element'; +import { ARIAGlobalStatesAndProperties, StartEnd } from '../patterns/index.js'; +import type { StartEndOptions } from '../patterns/index.js'; +import { applyMixins } from '../utils/apply-mixins.js'; +import type { + AnchorButtonAppearance, + AnchorButtonShape, + AnchorButtonSize, + AnchorTarget, +} from './anchor-button.options.js'; /** - * The base class used for constructing a fluent-anchor-button custom element + * Anchor configuration options * @public */ -export class AnchorButton extends FASTAnchor { +export type AnchorOptions = StartEndOptions; + +/** + * An Anchor Custom HTML Element. + * Based largely on the {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a | element }. + * + * @slot start - Content which can be provided before the anchor content + * @slot end - Content which can be provided after the anchor content + * @slot - The default slot for anchor content + * @csspart control - The anchor element + * @csspart content - The element wrapping anchor content + * + * @public + */ +export class AnchorButton extends FASTElement { + /** + * Prompts the user to save the linked URL. See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a | element } for more information. + * @public + * @remarks + * HTML Attribute: download + */ + @attr + public download!: string; + + /** + * The URL the hyperlink references. See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a | element } for more information. + * @public + * @remarks + * HTML Attribute: href + */ + @attr + public href!: string; + + /** + * Hints at the language of the referenced resource. See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a | element } for more information. + * @public + * @remarks + * HTML Attribute: hreflang + */ + @attr + public hreflang!: string; + + /** + * See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a | element } for more information. + * @public + * @remarks + * HTML Attribute: ping + */ + @attr + public ping!: string; + + /** + * See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a | element } for more information. + * @public + * @remarks + * HTML Attribute: referrerpolicy + */ + @attr + public referrerpolicy!: string; + + /** + * See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a | element } for more information. + * @public + * @remarks + * HTML Attribute: rel + */ + @attr + public rel!: string; + + /** + * See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a | element } for more information. + * @public + * @remarks + * HTML Attribute: target + */ + @attr + public target!: AnchorTarget; + + /** + * See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a | element } for more information. + * @public + * @remarks + * HTML Attribute: type + */ + @attr + public type!: string; + + /** + * + * Default slotted content + * + * @internal + */ + @observable + public defaultSlottedContent!: HTMLElement[]; + + /** + * References the root element + */ + public control!: HTMLAnchorElement; + /** * The appearance the anchor button should have. * @@ -109,3 +216,39 @@ export class AnchorButton extends FASTAnchor { ((this as unknown) as HTMLElement).removeEventListener('click', this.handleDisabledFocusableClick); } } + +/** + * Includes ARIA states and properties relating to the ARIA link role + * + * @public + */ +export class DelegatesARIALink { + /** + * See {@link https://www.w3.org/WAI/PF/aria/roles#link} for more information + * @public + * @remarks + * HTML Attribute: aria-expanded + */ + @attr({ attribute: 'aria-expanded' }) + public ariaExpanded!: 'true' | 'false' | string | null; +} + +/** + * Mark internal because exporting class and interface of the same name + * confuses API documenter. + * TODO: https://github.com/microsoft/fast/issues/3317 + * @internal + */ +/* eslint-disable-next-line @typescript-eslint/no-empty-interface */ +export interface DelegatesARIALink extends ARIAGlobalStatesAndProperties {} +applyMixins(DelegatesARIALink, ARIAGlobalStatesAndProperties); + +/** + * Mark internal because exporting class and interface of the same name + * confuses API documenter. + * TODO: https://github.com/microsoft/fast/issues/3317 + * @internal + */ +/* eslint-disable-next-line @typescript-eslint/no-empty-interface */ +export interface AnchorButton extends StartEnd, DelegatesARIALink {} +applyMixins(AnchorButton, StartEnd, DelegatesARIALink); diff --git a/packages/web-components/src/avatar/avatar.options.ts b/packages/web-components/src/avatar/avatar.options.ts index 2bbaa8b6b5ad2..1907e1a6bd9e0 100644 --- a/packages/web-components/src/avatar/avatar.options.ts +++ b/packages/web-components/src/avatar/avatar.options.ts @@ -1,4 +1,4 @@ -import type { ValuesOf } from '@microsoft/fast-foundation/utilities.js'; +import type { ValuesOf } from '../utils/index.js'; /** * The Avatar "active" state diff --git a/packages/web-components/src/badge/badge.definition.ts b/packages/web-components/src/badge/badge.definition.ts index f15da6d05174f..8996056d36563 100644 --- a/packages/web-components/src/badge/badge.definition.ts +++ b/packages/web-components/src/badge/badge.definition.ts @@ -4,9 +4,6 @@ import { styles } from './badge.styles.js'; import { template } from './badge.template.js'; /** - * The Fluent Badge Element. Implements {@link @microsoft/fast-foundation#Badge }, - * {@link @microsoft/fast-foundation#badgeTemplate} - * * * @public * @remarks diff --git a/packages/web-components/src/badge/badge.options.ts b/packages/web-components/src/badge/badge.options.ts index 52562f453dc56..81bae07d0bdb3 100644 --- a/packages/web-components/src/badge/badge.options.ts +++ b/packages/web-components/src/badge/badge.options.ts @@ -1,5 +1,5 @@ -import { StartEndOptions } from '@microsoft/fast-foundation/patterns.js'; -import type { StaticallyComposableHTML, ValuesOf } from '@microsoft/fast-foundation/utilities.js'; +import { StartEndOptions } from '../patterns/index.js'; +import type { StaticallyComposableHTML, ValuesOf } from '../utils/index.js'; import type { Badge } from './badge.js'; /** diff --git a/packages/web-components/src/badge/badge.template.ts b/packages/web-components/src/badge/badge.template.ts index d73589bec0e3b..6480f25b89069 100644 --- a/packages/web-components/src/badge/badge.template.ts +++ b/packages/web-components/src/badge/badge.template.ts @@ -1,6 +1,6 @@ import { ElementViewTemplate, html } from '@microsoft/fast-element'; -import { endSlotTemplate, startSlotTemplate } from '@microsoft/fast-foundation/patterns.js'; -import { staticallyCompose } from '@microsoft/fast-foundation/utilities.js'; +import { endSlotTemplate, startSlotTemplate } from '../patterns/index.js'; +import { staticallyCompose } from '../utils/template-helpers.js'; import type { Badge } from './badge.js'; import type { BadgeOptions } from './badge.options.js'; diff --git a/packages/web-components/src/badge/badge.ts b/packages/web-components/src/badge/badge.ts index 67163d66652bb..cca5925e1c5ad 100644 --- a/packages/web-components/src/badge/badge.ts +++ b/packages/web-components/src/badge/badge.ts @@ -1,7 +1,7 @@ import { attr, FASTElement } from '@microsoft/fast-element'; -import { StartEnd } from '@microsoft/fast-foundation/patterns.js'; // TODO: Remove with https://github.com/microsoft/fast/pull/6797 import { applyMixins } from '../utils/apply-mixins.js'; +import { StartEnd } from '../patterns/index.js'; import { BadgeAppearance, BadgeColor, BadgeShape, BadgeSize } from './badge.options.js'; /** diff --git a/packages/web-components/src/button/button.definition.ts b/packages/web-components/src/button/button.definition.ts index dad785060b687..84cb52407ea98 100644 --- a/packages/web-components/src/button/button.definition.ts +++ b/packages/web-components/src/button/button.definition.ts @@ -4,9 +4,6 @@ import { styles } from './button.styles.js'; import { template } from './button.template.js'; /** - * The Fluent Button Element. Implements {@link @microsoft/fast-foundation#Button }, - * {@link @microsoft/fast-foundation#buttonTemplate} - * * @public * @remarks * HTML Element: \ diff --git a/packages/web-components/src/button/button.form-associated.ts b/packages/web-components/src/button/button.form-associated.ts new file mode 100644 index 0000000000000..718a2cccb0c60 --- /dev/null +++ b/packages/web-components/src/button/button.form-associated.ts @@ -0,0 +1,13 @@ +import { FASTElement } from '@microsoft/fast-element'; +import { FormAssociated } from '../form-associated/form-associated.js'; + +class _Button extends FASTElement {} +/* eslint-disable-next-line @typescript-eslint/no-empty-interface */ +interface _Button extends FormAssociated {} + +/** + * @beta + */ +export class FormAssociatedButton extends FormAssociated(_Button) { + proxy = document.createElement('input'); +} diff --git a/packages/web-components/src/button/button.options.ts b/packages/web-components/src/button/button.options.ts index 0e89d77ce3988..5a265819ffe32 100644 --- a/packages/web-components/src/button/button.options.ts +++ b/packages/web-components/src/button/button.options.ts @@ -1,5 +1,6 @@ -import type { ButtonOptions } from '@microsoft/fast-foundation/button.js'; -import type { ValuesOf } from '@microsoft/fast-foundation/utilities.js'; +import { StartEndOptions } from '../patterns/index.js'; +import type { ValuesOf } from '../utils/index.js'; +import type { Button } from './button.js'; /** * ButtonAppearance constants @@ -51,4 +52,26 @@ export const ButtonSize = { */ export type ButtonSize = ValuesOf; -export { ButtonOptions }; +/** + * Button type values. + * + * @public + */ +export const ButtonType = { + submit: 'submit', + reset: 'reset', + button: 'button', +} as const; + +/** + * Type for button type values. + * + * @public + */ +export type ButtonType = ValuesOf; + +/** + * Button configuration options + * @public + */ +export type ButtonOptions = StartEndOptions + `; +} + export const template: ElementViewTemplate