Skip to content

Commit

Permalink
feat: add search web component (#21177)
Browse files Browse the repository at this point in the history
* feat: add search web component
  • Loading branch information
eljefe223 authored Jan 6, 2022
1 parent 0980427 commit ebe29c6
Show file tree
Hide file tree
Showing 14 changed files with 711 additions and 45 deletions.
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

0 comments on commit ebe29c6

Please sign in to comment.