Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add search web component #21177

Merged
merged 10 commits into from
Jan 6, 2022
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "feat: add search web component",
"packageName": "@fluentui/web-components",
"email": "[email protected]",
"dependentChangeType": "patch"
}
43 changes: 34 additions & 9 deletions packages/web-components/docs/api-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ 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 } 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';
Expand All @@ -56,6 +56,8 @@ 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';
Expand Down Expand Up @@ -211,6 +213,7 @@ export const allComponents: {
fluentProgressRing: (overrideDefinition?: OverrideFoundationElementDefinition<ProgressRingOptions> | undefined) => FoundationElementRegistry<ProgressRingOptions, Constructable<FoundationElement>>;
fluentRadio: (overrideDefinition?: OverrideFoundationElementDefinition<RadioOptions> | undefined) => FoundationElementRegistry<RadioOptions, Constructable<FoundationElement>>;
fluentRadioGroup: (overrideDefinition?: OverrideFoundationElementDefinition<FoundationElementDefinition> | undefined) => FoundationElementRegistry<FoundationElementDefinition, RadioGroup>;
fluentSearch: (overrideDefinition?: OverrideFoundationElementDefinition<SearchOptions> | undefined) => FoundationElementRegistry<SearchOptions, Constructable<FoundationElement>>;
fluentSelect: (overrideDefinition?: OverrideFoundationElementDefinition<SelectOptions> | undefined) => FoundationElementRegistry<SelectOptions, Constructable<FoundationElement>>;
fluentSkeleton: (overrideDefinition?: OverrideFoundationElementDefinition<FoundationElementDefinition> | undefined) => FoundationElementRegistry<FoundationElementDefinition, Skeleton>;
fluentSlider: (overrideDefinition?: OverrideFoundationElementDefinition<SliderOptions> | undefined) => FoundationElementRegistry<SliderOptions, Constructable<FoundationElement>>;
Expand Down Expand Up @@ -649,6 +652,9 @@ export const fluentRadio: (overrideDefinition?: OverrideFoundationElementDefinit
// @public
export const fluentRadioGroup: (overrideDefinition?: OverrideFoundationElementDefinition<FoundationElementDefinition> | undefined) => FoundationElementRegistry<FoundationElementDefinition, typeof RadioGroup>;

// @public
export const fluentSearch: (overrideDefinition?: OverrideFoundationElementDefinition<SearchOptions> | undefined) => FoundationElementRegistry<SearchOptions, Constructable<FoundationElement>>;

// @public
export const fluentSelect: (overrideDefinition?: OverrideFoundationElementDefinition<SelectOptions> | undefined) => FoundationElementRegistry<SelectOptions, Constructable<FoundationElement>>;

Expand Down Expand Up @@ -818,7 +824,9 @@ export const layerCornerRadius: CSSDesignToken<number>;
// @internal (undocumented)
export const LightweightButtonStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition, interactivitySelector?: string, nonInteractivitySelector?: string) => ElementStyles;

export { Listbox }
// @public (undocumented)
export class Listbox extends Listbox_2 {
}

// @public
export const listboxStyles: (context: ElementDefinitionContext, definition: FoundationElementDefinition) => ElementStyles;
Expand Down Expand Up @@ -1413,6 +1421,23 @@ export interface Recipe<T> {
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: any, definition: any) => ElementStyles;

// @public (undocumented)
export const searchTemplate: (context: ElementDefinitionContext, definition: SearchOptions) => ViewTemplate<Search_2>;

// Warning: (ae-internal-missing-underscore) The name "Select" should be prefixed with an underscore because the declaration is marked as @internal
//
// @internal
Expand Down Expand Up @@ -1628,13 +1653,13 @@ export const typeRampPlus6LineHeight: CSSDesignToken<string>;
//
// 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:50: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:52: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:55: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:93: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:94: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:95: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:96:5 - (ae-incompatible-release-tags) The symbol "fluentTooltip" is marked as @public, but its signature references "Tooltip" which is marked as @internal
// dist/dts/custom-elements.d.ts:51: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:53: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:56: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:95: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:96: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:97: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:98:5 - (ae-incompatible-release-tags) The symbol "fluentTooltip" is marked as @public, but its signature references "Tooltip" which is marked as @internal

// (No @packageDocumentation comment for this package)

Expand Down
2 changes: 1 addition & 1 deletion packages/web-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
"dependencies": {
"@microsoft/fast-colors": "^5.1.0",
"@microsoft/fast-element": "^1.6.0",
"@microsoft/fast-foundation": "^2.24.0",
"@microsoft/fast-foundation": "^2.27.1",
"@microsoft/fast-web-utilities": "^5.0.0",
"tslib": "^1.13.0"
}
Expand Down
2 changes: 2 additions & 0 deletions packages/web-components/src/component-definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ 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';
Expand Down
3 changes: 3 additions & 0 deletions packages/web-components/src/custom-elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ 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';
Expand Down Expand Up @@ -70,6 +71,7 @@ export {
fluentProgressRing,
fluentRadio,
fluentRadioGroup,
fluentSearch,
fluentSelect,
fluentSkeleton,
fluentSlider,
Expand Down Expand Up @@ -120,6 +122,7 @@ export const allComponents = {
fluentProgressRing,
fluentRadio,
fluentRadioGroup,
fluentSearch,
fluentSelect,
fluentSkeleton,
fluentSlider,
Expand Down
1 change: 1 addition & 0 deletions packages/web-components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ 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/';
Expand Down
10 changes: 3 additions & 7 deletions packages/web-components/src/listbox/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Listbox, listboxTemplate as template } from '@microsoft/fast-foundation';
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}
Expand All @@ -22,9 +24,3 @@ export const fluentListbox = Listbox.compose({
* @public
*/
export const listboxStyles = styles;

/**
* Listbox base class
* @public
*/
export { Listbox };
109 changes: 109 additions & 0 deletions packages/web-components/src/search/fixtures/search.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<h1>Search</h1>
<h4>Default</h4>
<fluent-search></fluent-search>
<fluent-search>Label</fluent-search>

<h4>Full Width</h4>
<fluent-search style="width: 100%"></fluent-search>

<h4>Placeholder</h4>
<fluent-search placeholder="Placeholder"></fluent-search>

<!-- Required -->
<h4>Required</h4>
<fluent-search required></fluent-search>

<!-- Disabled -->
<h4>Disabled</h4>
<fluent-search disabled></fluent-search>
<fluent-search disabled>label</fluent-search>
<fluent-search disabled placeholder="placeholder"></fluent-search>
<fluent-search disabled>
<svg slot="start" width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path
d="M12 5.5a1 1 0 100 2 1 1 0 000-2zm-5 1a1 1 0 112 0 1 1 0 01-2 0zm3.5-4a.5.5 0 00-1 0V3h-3C5.67 3 5 3.67 5 4.5v4c0 .83.67 1.5 1.5 1.5h7c.83 0 1.5-.67 1.5-1.5v-4c0-.83-.67-1.5-1.5-1.5h-3v-.5zM6.5 4h7c.28 0 .5.22.5.5v4a.5.5 0 01-.5.5h-7a.5.5 0 01-.5-.5v-4c0-.28.22-.5.5-.5zm3.75 14c2.62-.04 4.2-.6 5.12-1.44A3.52 3.52 0 0016.5 14h.01v-.69c0-1-.81-1.8-1.8-1.8h-3.2v-.01H5.3c-.99 0-1.8.81-1.8 1.81v.7c.04.77.25 1.75 1.13 2.55.93.84 2.5 1.4 5.12 1.44h.5zm-4.94-5.5h9.38c.45 0 .81.37.81.81v.44c0 .69-.13 1.46-.8 2.07C14 16.45 12.66 17 10 17s-4.01-.55-4.7-1.18a2.63 2.63 0 01-.8-2.07v-.44c0-.44.36-.8.8-.8z"
/>
</svg>
</fluent-search>

<!-- Read only -->
<h4>Read only</h4>
<fluent-search readonly value="Readonly"></fluent-search>
<fluent-search readonly value="Readonly">label</fluent-search>

<!-- Read only -->
<h4>Autofocus</h4>
<fluent-search autofocus>autofocus</fluent-search>

<!-- Start -->
<h4>With start</h4>
<fluent-search>
<svg slot="start" width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path
d="M12 5.5a1 1 0 100 2 1 1 0 000-2zm-5 1a1 1 0 112 0 1 1 0 01-2 0zm3.5-4a.5.5 0 00-1 0V3h-3C5.67 3 5 3.67 5 4.5v4c0 .83.67 1.5 1.5 1.5h7c.83 0 1.5-.67 1.5-1.5v-4c0-.83-.67-1.5-1.5-1.5h-3v-.5zM6.5 4h7c.28 0 .5.22.5.5v4a.5.5 0 01-.5.5h-7a.5.5 0 01-.5-.5v-4c0-.28.22-.5.5-.5zm3.75 14c2.62-.04 4.2-.6 5.12-1.44A3.52 3.52 0 0016.5 14h.01v-.69c0-1-.81-1.8-1.8-1.8h-3.2v-.01H5.3c-.99 0-1.8.81-1.8 1.81v.7c.04.77.25 1.75 1.13 2.55.93.84 2.5 1.4 5.12 1.44h.5zm-4.94-5.5h9.38c.45 0 .81.37.81.81v.44c0 .69-.13 1.46-.8 2.07C14 16.45 12.66 17 10 17s-4.01-.55-4.7-1.18a2.63 2.63 0 01-.8-2.07v-.44c0-.44.36-.8.8-.8z"
/>
</svg>
</fluent-search>

<!-- End -->
<h4>With end</h4>
<fluent-search>
<svg slot="end" width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path
d="M12 5.5a1 1 0 100 2 1 1 0 000-2zm-5 1a1 1 0 112 0 1 1 0 01-2 0zm3.5-4a.5.5 0 00-1 0V3h-3C5.67 3 5 3.67 5 4.5v4c0 .83.67 1.5 1.5 1.5h7c.83 0 1.5-.67 1.5-1.5v-4c0-.83-.67-1.5-1.5-1.5h-3v-.5zM6.5 4h7c.28 0 .5.22.5.5v4a.5.5 0 01-.5.5h-7a.5.5 0 01-.5-.5v-4c0-.28.22-.5.5-.5zm3.75 14c2.62-.04 4.2-.6 5.12-1.44A3.52 3.52 0 0016.5 14h.01v-.69c0-1-.81-1.8-1.8-1.8h-3.2v-.01H5.3c-.99 0-1.8.81-1.8 1.81v.7c.04.77.25 1.75 1.13 2.55.93.84 2.5 1.4 5.12 1.44h.5zm-4.94-5.5h9.38c.45 0 .81.37.81.81v.44c0 .69-.13 1.46-.8 2.07C14 16.45 12.66 17 10 17s-4.01-.55-4.7-1.18a2.63 2.63 0 01-.8-2.07v-.44c0-.44.36-.8.8-.8z"
/>
</svg>
</fluent-search>

<h4>Filled</h4>
<h5>Default</h5>
<fluent-search appearance="filled"></fluent-search>
<fluent-search appearance="filled">label</fluent-search>

<h5>Placeholder</h5>
<fluent-search appearance="filled" placeholder="Placeholder"></fluent-search>

<!-- Required -->
<h5>Required</h5>
<fluent-search appearance="filled" required></fluent-search>

<!-- Disabled -->
<h5>Disabled</h5>
<fluent-search appearance="filled" disabled></fluent-search>
<fluent-search appearance="filled" disabled>label</fluent-search>
<fluent-search appearance="filled" disabled placeholder="placeholder"></fluent-search>
<fluent-search appearance="filled" disabled>
<svg slot="start" width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path
d="M12 5.5a1 1 0 100 2 1 1 0 000-2zm-5 1a1 1 0 112 0 1 1 0 01-2 0zm3.5-4a.5.5 0 00-1 0V3h-3C5.67 3 5 3.67 5 4.5v4c0 .83.67 1.5 1.5 1.5h7c.83 0 1.5-.67 1.5-1.5v-4c0-.83-.67-1.5-1.5-1.5h-3v-.5zM6.5 4h7c.28 0 .5.22.5.5v4a.5.5 0 01-.5.5h-7a.5.5 0 01-.5-.5v-4c0-.28.22-.5.5-.5zm3.75 14c2.62-.04 4.2-.6 5.12-1.44A3.52 3.52 0 0016.5 14h.01v-.69c0-1-.81-1.8-1.8-1.8h-3.2v-.01H5.3c-.99 0-1.8.81-1.8 1.81v.7c.04.77.25 1.75 1.13 2.55.93.84 2.5 1.4 5.12 1.44h.5zm-4.94-5.5h9.38c.45 0 .81.37.81.81v.44c0 .69-.13 1.46-.8 2.07C14 16.45 12.66 17 10 17s-4.01-.55-4.7-1.18a2.63 2.63 0 01-.8-2.07v-.44c0-.44.36-.8.8-.8z"
/>
</svg>
</fluent-search>

<!-- Read only -->
<h5>Read only</h5>
<fluent-search appearance="filled" readonly value="Readonly"></fluent-search>
<fluent-search appearance="filled" readonly value="Readonly">label</fluent-search>

<!-- With label -->
<h4>Visual vs audio label</h4>
<fluent-search>
<span aria-label="Audio label">Visible label</span>
</fluent-search>

<!-- With hidden label -->
<h4>Audio label only</h4>
<fluent-search>
<span aria-label="Audio label only"></span>
</fluent-search>

<!-- With aria-label -->
<h4>With aria-label</h4>
<fluent-search aria-label="Search with aria-label"></fluent-search>

<form class="form" name="myForm" action="#">
<!-- In a form -->
<h2>In a form</h2>
<fluent-search name="fname" aria-label="Search with aria-label"></fluent-search>
<input type="submit" value="submit" />
</form>
56 changes: 56 additions & 0 deletions packages/web-components/src/search/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
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: \<fluent-search\>
*
* {@link https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus | delegatesFocus}
*/
export const fluentSearch = Search.compose<SearchOptions>({
baseName: 'search',
baseClass: FoundationSearch,
template,
styles,
start: `<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg%22%3E"><path d="M8.5 3a5.5 5.5 0 0 1 4.23 9.02l4.12 4.13a.5.5 0 0 1-.63.76l-.07-.06-4.13-4.12A5.5 5.5 0 1 1 8.5 3Zm0 1a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9Z"/></svg>`,
shadowOptions: {
delegatesFocus: true,
},
});

export * from './search.template';

/**
* Styles for Search
* @public
*/
export const searchStyles = styles;
Loading