@ongov/ontario-design-system-component-library 4.3.1-alpha.1 → 5.0.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/dist/cjs/app-globals-6f6b30a8.js.map +1 -1
  2. package/dist/cjs/index-88d5cf20.js +2 -2
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/{ontario-accordion_43.cjs.entry.js → ontario-accordion_44.cjs.entry.js} +358 -85
  5. package/dist/cjs/ontario-accordion_44.cjs.entry.js.map +1 -0
  6. package/dist/cjs/ontario-design-system-components.cjs.js +1 -1
  7. package/dist/collection/collection-manifest.json +1 -0
  8. package/dist/collection/components/ontario-card/ontario-card-types.js +29 -2
  9. package/dist/collection/components/ontario-card/ontario-card-types.js.map +1 -1
  10. package/dist/collection/components/ontario-card/ontario-card.css +252 -34
  11. package/dist/collection/components/ontario-card/ontario-card.js +102 -78
  12. package/dist/collection/components/ontario-card/ontario-card.js.map +1 -1
  13. package/dist/collection/components/ontario-card/test/ontario-cards.spec.js +23 -13
  14. package/dist/collection/components/ontario-card/test/ontario-cards.spec.js.map +1 -1
  15. package/dist/collection/components/ontario-date-input/test/ontario-date-input.spec.js +58 -0
  16. package/dist/collection/components/ontario-date-input/test/ontario-date-input.spec.js.map +1 -1
  17. package/dist/collection/components/ontario-date-input/utils/date-validation-utils.js +14 -4
  18. package/dist/collection/components/ontario-date-input/utils/date-validation-utils.js.map +1 -1
  19. package/dist/collection/components/ontario-header/service-ontario-header.css +0 -3
  20. package/dist/collection/components/ontario-search-box/assets/ontario-icon-close.svg +1 -0
  21. package/dist/collection/components/ontario-search-box/assets/ontario-logo--mobile.svg +6 -0
  22. package/dist/collection/components/ontario-search-box/ontario-search-box.css +823 -0
  23. package/dist/collection/components/ontario-search-box/ontario-search-box.js +584 -0
  24. package/dist/collection/components/ontario-search-box/ontario-search-box.js.map +1 -0
  25. package/dist/collection/components/ontario-search-box/test/ontario-search-box.e2e.js +20 -0
  26. package/dist/collection/components/ontario-search-box/test/ontario-search-box.e2e.js.map +1 -0
  27. package/dist/collection/components/ontario-search-box/test/ontario-search-box.spec.js +19 -0
  28. package/dist/collection/components/ontario-search-box/test/ontario-search-box.spec.js.map +1 -0
  29. package/dist/collection/components/ontario-step-indicator/ontario-step-indicator.js +5 -5
  30. package/dist/collection/components/ontario-table/ontario-table.js +5 -5
  31. package/dist/collection/components/ontario-textarea/ontario-textarea.js +3 -3
  32. package/dist/collection/fonts/open-sans-400/LICENSE.txt +0 -0
  33. package/dist/collection/fonts/open-sans-400/open-sans-400.eot +0 -0
  34. package/dist/collection/fonts/open-sans-400/open-sans-400.svg +0 -0
  35. package/dist/collection/fonts/open-sans-400/open-sans-400.ttf +0 -0
  36. package/dist/collection/fonts/open-sans-400/open-sans-400.woff +0 -0
  37. package/dist/collection/fonts/open-sans-400/open-sans-400.woff2 +0 -0
  38. package/dist/collection/fonts/open-sans-700/LICENSE.txt +0 -0
  39. package/dist/collection/fonts/open-sans-700/open-sans-700.eot +0 -0
  40. package/dist/collection/fonts/open-sans-700/open-sans-700.svg +0 -0
  41. package/dist/collection/fonts/open-sans-700/open-sans-700.ttf +0 -0
  42. package/dist/collection/utils/common/input/input.js +3 -0
  43. package/dist/collection/utils/common/input/input.js.map +1 -1
  44. package/dist/collection/utils/common/input-caption/input-caption.js +5 -3
  45. package/dist/collection/utils/common/input-caption/input-caption.js.map +1 -1
  46. package/dist/collection/utils/helper/utils.js +4 -2
  47. package/dist/collection/utils/helper/utils.js.map +1 -1
  48. package/dist/collection/utils/helper/utils.spec.js +99 -1
  49. package/dist/collection/utils/helper/utils.spec.js.map +1 -1
  50. package/dist/components/error-message.js +1 -324
  51. package/dist/components/error-message.js.map +1 -1
  52. package/dist/components/event-handler.js +330 -0
  53. package/dist/components/event-handler.js.map +1 -0
  54. package/dist/components/input.js +3 -0
  55. package/dist/components/input.js.map +1 -1
  56. package/dist/components/ontario-card.js +116 -64
  57. package/dist/components/ontario-card.js.map +1 -1
  58. package/dist/components/ontario-checkboxes.js +2 -1
  59. package/dist/components/ontario-checkboxes.js.map +1 -1
  60. package/dist/components/ontario-date-input.js +15 -4
  61. package/dist/components/ontario-date-input.js.map +1 -1
  62. package/dist/components/ontario-dropdown-list.js +2 -1
  63. package/dist/components/ontario-dropdown-list.js.map +1 -1
  64. package/dist/components/ontario-header.js +4 -6
  65. package/dist/components/ontario-header.js.map +1 -1
  66. package/dist/components/ontario-icon-search2.js +6 -0
  67. package/dist/components/ontario-icon-search2.js.map +1 -0
  68. package/dist/components/ontario-input.js +2 -1
  69. package/dist/components/ontario-input.js.map +1 -1
  70. package/dist/components/ontario-radio-buttons.js +2 -1
  71. package/dist/components/ontario-radio-buttons.js.map +1 -1
  72. package/dist/components/ontario-search-box.d.ts +11 -0
  73. package/dist/components/ontario-search-box.js +269 -0
  74. package/dist/components/ontario-search-box.js.map +1 -0
  75. package/dist/components/ontario-step-indicator.js +5 -5
  76. package/dist/components/ontario-table.js +5 -5
  77. package/dist/components/ontario-textarea.js +5 -4
  78. package/dist/components/ontario-textarea.js.map +1 -1
  79. package/dist/components/utils.js +4 -2
  80. package/dist/components/utils.js.map +1 -1
  81. package/dist/esm/app-globals-70748594.js.map +1 -1
  82. package/dist/esm/index-603026f7.js +2 -2
  83. package/dist/esm/loader.js +1 -1
  84. package/dist/esm/{ontario-accordion_43.entry.js → ontario-accordion_44.entry.js} +358 -85
  85. package/dist/esm/ontario-accordion_44.entry.js.map +1 -0
  86. package/dist/esm/ontario-design-system-components.js +1 -1
  87. package/dist/esm/polyfills/core-js.js +0 -0
  88. package/dist/esm/polyfills/dom.js +0 -0
  89. package/dist/esm/polyfills/es5-html-element.js +0 -0
  90. package/dist/esm/polyfills/index.js +0 -0
  91. package/dist/esm/polyfills/system.js +0 -0
  92. package/dist/ontario-design-system-components/fonts/open-sans-400/LICENSE.txt +0 -0
  93. package/dist/ontario-design-system-components/fonts/open-sans-400/open-sans-400.eot +0 -0
  94. package/dist/ontario-design-system-components/fonts/open-sans-400/open-sans-400.svg +0 -0
  95. package/dist/ontario-design-system-components/fonts/open-sans-400/open-sans-400.ttf +0 -0
  96. package/dist/ontario-design-system-components/fonts/open-sans-400/open-sans-400.woff +0 -0
  97. package/dist/ontario-design-system-components/fonts/open-sans-400/open-sans-400.woff2 +0 -0
  98. package/dist/ontario-design-system-components/fonts/open-sans-700/LICENSE.txt +0 -0
  99. package/dist/ontario-design-system-components/fonts/open-sans-700/open-sans-700.eot +0 -0
  100. package/dist/ontario-design-system-components/fonts/open-sans-700/open-sans-700.svg +0 -0
  101. package/dist/ontario-design-system-components/fonts/open-sans-700/open-sans-700.ttf +0 -0
  102. package/dist/ontario-design-system-components/ontario-design-system-components.esm.js +1 -1
  103. package/dist/ontario-design-system-components/ontario-design-system-components.esm.js.map +1 -1
  104. package/dist/ontario-design-system-components/p-103a233b.js.map +1 -1
  105. package/dist/ontario-design-system-components/{p-abe58ec9.entry.js → p-ac4e76b2.entry.js} +1927 -1728
  106. package/dist/ontario-design-system-components/p-ac4e76b2.entry.js.map +1 -0
  107. package/dist/types/components/ontario-card/ontario-card-types.d.ts +4 -4
  108. package/dist/types/components/ontario-card/ontario-card.d.ts +40 -29
  109. package/dist/types/components/ontario-date-input/utils/date-validation-utils.d.ts +14 -0
  110. package/dist/types/components/ontario-search-box/ontario-search-box.d.ts +180 -0
  111. package/dist/types/components.d.ts +199 -16
  112. package/dist/types/utils/common/input/input.d.ts +2 -1
  113. package/dist/types/utils/common/input-caption/input-caption.d.ts +7 -1
  114. package/package.json +3 -3
  115. package/src/components/ontario-card/ontario-card-types.tsx +33 -4
  116. package/src/components/ontario-card/ontario-card.scss +54 -40
  117. package/src/components/ontario-card/ontario-card.tsx +94 -68
  118. package/src/components/ontario-card/readme.md +57 -27
  119. package/src/components/ontario-card/test/__snapshots__/ontario-cards.spec.tsx.snap +66 -0
  120. package/src/components/ontario-card/test/ontario-cards.spec.tsx +27 -13
  121. package/src/components/ontario-card-collection/readme.md +13 -13
  122. package/src/components/ontario-checkbox/ontario-checkboxes.scss +0 -1
  123. package/src/components/ontario-date-input/test/ontario-date-input.spec.tsx +76 -0
  124. package/src/components/ontario-date-input/utils/date-validation-utils.ts +18 -4
  125. package/src/components/ontario-header/service-ontario-header.scss +0 -4
  126. package/src/components/ontario-hint-text/readme.md +2 -0
  127. package/src/components/ontario-radio-buttons/ontario-radio-buttons.scss +0 -1
  128. package/src/components/ontario-search-box/assets/ontario-icon-close.svg +1 -0
  129. package/src/components/ontario-search-box/assets/ontario-logo--mobile.svg +6 -0
  130. package/src/components/ontario-search-box/ontario-search-box.scss +141 -0
  131. package/src/components/ontario-search-box/ontario-search-box.tsx +341 -0
  132. package/src/components/ontario-search-box/readme.md +132 -0
  133. package/src/components/ontario-search-box/test/__snapshots__/ontario-search-box.spec.tsx.snap +35 -0
  134. package/src/components/ontario-search-box/test/ontario-search-box.e2e.ts +21 -0
  135. package/src/components/ontario-search-box/test/ontario-search-box.spec.tsx +22 -0
  136. package/src/components.d.ts +199 -16
  137. package/src/config.json +1 -4
  138. package/src/index.html +287 -52
  139. package/src/utils/common/input/input.tsx +4 -1
  140. package/src/utils/common/input-caption/input-caption.tsx +9 -3
  141. package/src/utils/helper/utils.spec.ts +127 -1
  142. package/src/utils/helper/utils.ts +4 -2
  143. package/www/build/ontario-design-system-components.esm.js +1 -1
  144. package/www/build/ontario-design-system-components.esm.js.map +1 -1
  145. package/www/build/p-103a233b.js.map +1 -1
  146. package/www/build/{p-abe58ec9.entry.js → p-ac4e76b2.entry.js} +1927 -1728
  147. package/www/build/p-ac4e76b2.entry.js.map +1 -0
  148. package/www/build/{p-fdc9ab6d.js → p-c9a9b857.js} +1 -1
  149. package/www/fonts/open-sans-400/LICENSE.txt +0 -0
  150. package/www/fonts/open-sans-400/open-sans-400.eot +0 -0
  151. package/www/fonts/open-sans-400/open-sans-400.svg +0 -0
  152. package/www/fonts/open-sans-400/open-sans-400.ttf +0 -0
  153. package/www/fonts/open-sans-400/open-sans-400.woff +0 -0
  154. package/www/fonts/open-sans-400/open-sans-400.woff2 +0 -0
  155. package/www/fonts/open-sans-700/LICENSE.txt +0 -0
  156. package/www/fonts/open-sans-700/open-sans-700.eot +0 -0
  157. package/www/fonts/open-sans-700/open-sans-700.svg +0 -0
  158. package/www/fonts/open-sans-700/open-sans-700.ttf +0 -0
  159. package/www/index.html +261 -52
  160. package/dist/cjs/ontario-accordion_43.cjs.entry.js.map +0 -1
  161. package/dist/esm/ontario-accordion_43.entry.js.map +0 -1
  162. package/dist/ontario-design-system-components/p-abe58ec9.entry.js.map +0 -1
  163. package/www/build/p-abe58ec9.entry.js.map +0 -1
@@ -0,0 +1,341 @@
1
+ import { Component, Prop, h, Element, EventEmitter, Event, AttachInternals, State, Watch } from '@stencil/core';
2
+ import { Input } from '../../utils/common/input/input';
3
+ import { Language } from '../../utils/common/language-types';
4
+ import OntarioIconSearch from '../ontario-icon/assets/ontario-icon-search.svg';
5
+ import { Hint } from '../../utils/common/common.interface';
6
+ import { handleInputEvent } from '../../utils/events/event-handler';
7
+ import {
8
+ InputFocusBlurEvent,
9
+ EventType,
10
+ InputInteractionEvent,
11
+ InputInputEvent,
12
+ } from '../../utils/events/event-handler.interface';
13
+ import { Caption } from '../../utils/common/input-caption/caption.interface';
14
+ import { InputCaption } from '../../utils/common/input-caption/input-caption';
15
+ import { default as translations } from '../../translations/global.i18n.json';
16
+ import { constructHintTextObject } from '../../utils/components/hints/hints';
17
+
18
+ @Component({
19
+ tag: 'ontario-search-box',
20
+ styleUrl: 'ontario-search-box.scss',
21
+ shadow: true,
22
+ })
23
+ export class OntarioSearchBox {
24
+ @Element() element: HTMLElement;
25
+ @AttachInternals() internals: ElementInternals;
26
+
27
+ /**
28
+ * This Ref is used get a direct reference to the hint text element
29
+ */
30
+ private hintTextRef?: HTMLOntarioHintTextElement;
31
+
32
+ /**
33
+ * This Ref is used get a direct reference to the search input element
34
+ */
35
+ private inputFieldRef?: HTMLInputElement;
36
+
37
+ /**
38
+ * The language of the component.
39
+ * This is used for translations. If none is passed, it will default to English.
40
+ */
41
+ @Prop({ mutable: true }) language?: Language = 'en';
42
+
43
+ /**
44
+ * The unique identifier of the search-box component. This is optional - if no ID is passed, one will be generated.
45
+ */
46
+ @Prop({ mutable: true }) elementId?: string;
47
+
48
+ /**
49
+ * The value of the search term.
50
+ * This is optional.
51
+ */
52
+ @Prop({ mutable: true }) value?: string;
53
+
54
+ /**
55
+ * The text to display as the input label
56
+ *
57
+ * @example
58
+ * <ontario-search-box
59
+ *      caption='{
60
+ "captionText": "Search directory",
61
+ "captionType": "default"
62
+ }'
63
+ required = "true"
64
+ >
65
+ </ontario-search-box>
66
+ */
67
+ @Prop() caption: Caption | string;
68
+
69
+ /**
70
+ * This is used to determine whether the dropdown list is required or not.
71
+ * This prop gets passed to the InputCaption utility to display either an optional or required flag in the label.
72
+ * If no prop is set, it will default to false (optional).
73
+ */
74
+ @Prop() required?: boolean = false;
75
+
76
+ /**
77
+ * This Function to perform a search operation.
78
+ * This function will be called when the search submit button is triggered.
79
+ * The value argument is used for as search term to use for the search operation. This parameter is optional.
80
+ * The performSearch prop can be set dynamically using JavaScript, allowing you to define custom search functionality when the search form is submitted.
81
+ *
82
+ * @example
83
+ * <ontario-search-box
84
+ * id="ontario-search-box"
85
+ * caption='Search directory'
86
+ * ></ontario-search-box>
87
+ *
88
+ * <script>
89
+ * window.addEventListener('load', () => {
90
+ * const searchBox = document.getElementById('ontario-search-box');
91
+ * searchBox.performSearch = async (value) => {
92
+ * console.log('Performing search with value:', value);
93
+ * };
94
+ * });
95
+ * </script>
96
+ */
97
+ @Prop() performSearch?: (value?: string) => Promise<void>;
98
+
99
+ /**
100
+ * Used to include the ontario-hint-text component for the search-box.
101
+ * This is optional.
102
+ */
103
+ @Prop() hintText?: string | Hint;
104
+
105
+ /**
106
+ * Used to add a custom function to the input onInput event.
107
+ */
108
+ @Prop() customOnInput?: (event: globalThis.Event) => void;
109
+
110
+ /**
111
+ * Used to add a custom function to the input onChange event.
112
+ */
113
+ @Prop() customOnChange?: (event: globalThis.Event) => void;
114
+
115
+ /**
116
+ * Used to add a custom function to the input onBlur event.
117
+ */
118
+ @Prop() customOnBlur?: (event: globalThis.Event) => void;
119
+
120
+ /**
121
+ * Used to add a custom function to the input onFocus event.
122
+ */
123
+ @Prop() customOnFocus?: (event: globalThis.Event) => void;
124
+
125
+ /**
126
+ * Emitted when the search is submitted.
127
+ * Below is an example on how to hook into the event to get the event details.
128
+ *
129
+ * @example
130
+ * <script>
131
+ * document.getElementById('ontario-search-box').addEventListener('searchOnSubmit', (event) => {
132
+ * const searchValue = event.detail;
133
+ * console.log('Search submitted with value:', searchValue);
134
+ * };
135
+ * </script>
136
+ */
137
+ @Event() searchOnSubmit: EventEmitter<string>;
138
+
139
+ /**
140
+ * Emitted when a input  occurs when an input has been changed.
141
+ */
142
+ @Event() inputOnInput: EventEmitter<InputInputEvent>;
143
+
144
+ /**
145
+ * Emitted when a keyboard input or mouse event occurs when an input has been changed.
146
+ */
147
+ @Event() inputOnChange: EventEmitter<InputInteractionEvent>;
148
+
149
+ /**
150
+ * Emitted when a keyboard input event occurs when an input has lost focus.
151
+ */
152
+ @Event() inputOnBlur: EventEmitter<InputFocusBlurEvent>;
153
+
154
+ /**
155
+ * Emitted when a keyboard input event occurs when an input has gained focus.
156
+ */
157
+ @Event() inputOnFocus: EventEmitter<InputFocusBlurEvent>;
158
+
159
+ /**
160
+ * The hint text options are re-assigned to the internalHintText array.
161
+ */
162
+ @State() private internalHintText: Hint;
163
+
164
+ /**
165
+ * Instantiate an InputCaption object for internal logic use
166
+ */
167
+ @State() private captionState: InputCaption;
168
+
169
+ /**
170
+ * Used for the `aria-describedby` value of the dropdown list. This will match with the id of the hint text.
171
+ */
172
+ @State() hintTextId: string | null | undefined;
173
+
174
+ /**
175
+ * Watch for changes to the `hintText` prop.
176
+ *
177
+ * If a `hintText` prop is passed, the `constructHintTextObject` function will convert it to the correct format, and set the result to the `internalHintText` state.
178
+ */
179
+ @Watch('hintText')
180
+ private parseHintText() {
181
+ if (this.hintText) {
182
+ const hintTextObject = constructHintTextObject(this.hintText);
183
+ this.internalHintText = hintTextObject;
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Watch for changes to the `caption` prop.
189
+ *
190
+ * The caption will be run through the InputCaption constructor to convert it to the correct format, and set the result to the `captionState` state.
191
+ * @param newValue: Caption | string
192
+ */
193
+ @Watch('caption')
194
+ private updateCaptionState(newValue: Caption | string) {
195
+ this.captionState = new InputCaption(
196
+ this.element.tagName,
197
+ newValue,
198
+ translations,
199
+ this.language,
200
+ false,
201
+ this.required,
202
+ );
203
+ }
204
+
205
+ /**
206
+ * Watch for changes to the `language` prop to render either the English or French translations
207
+ */
208
+ @Watch('language')
209
+ updateLanguage() {
210
+ this.updateCaptionState(this.caption);
211
+ }
212
+
213
+ /**
214
+ * If a `hintText` prop is passed, the id generated from it will be set to the internal `hintTextId` state to match with the select `aria-describedBy` attribute.
215
+ */
216
+ async componentDidLoad() {
217
+ this.hintTextId = await this.hintTextRef?.getHintTextId();
218
+ }
219
+
220
+ componentWillLoad() {
221
+ this.elementId = this.elementId;
222
+ this.parseHintText();
223
+ this.updateCaptionState(this.caption);
224
+ }
225
+
226
+ /**
227
+ * Function to handle input events and the information pertaining to the input to emit.
228
+ */
229
+ private handleEvent(event: globalThis.Event, eventType: EventType) {
230
+ const input = event.target as HTMLInputElement | null;
231
+
232
+ // Update the component value to match the value of the input element.
233
+ this.value = input?.value;
234
+
235
+ this.internals?.setFormValue?.(this.value ?? '');
236
+
237
+ handleInputEvent(
238
+ event,
239
+ eventType,
240
+ input,
241
+ this.inputOnChange,
242
+ this.inputOnFocus,
243
+ this.inputOnBlur,
244
+ this.inputOnInput,
245
+ 'input',
246
+ this.customOnChange,
247
+ this.customOnFocus,
248
+ this.customOnBlur,
249
+ this.customOnInput,
250
+ this.element,
251
+ );
252
+ }
253
+
254
+ /**
255
+ * handleSearch function is called when the search submit button is clicked
256
+ */
257
+ async handleSearch(event: MouseEvent) {
258
+ event.preventDefault();
259
+ this.searchOnSubmit.emit(this.value);
260
+ this.performSearch && (await this.performSearch(this.value));
261
+ }
262
+
263
+ public getId(): string {
264
+ return this.elementId ?? '';
265
+ }
266
+
267
+ private getValue(): string | number {
268
+ return this.value ?? '';
269
+ }
270
+
271
+ /**
272
+ *This function ensures that the focus returns to the search input field when the reset button is clicked.
273
+ */
274
+ private setFocus(inputRef?: HTMLInputElement) {
275
+ if (inputRef) {
276
+ inputRef.focus();
277
+ }
278
+ }
279
+
280
+ /**
281
+ * when the reset button is clicked this function gets called
282
+ */
283
+ handleFocus = () => {
284
+ this.setFocus(this.inputFieldRef);
285
+ };
286
+
287
+ render() {
288
+ const searchInputFieldId: string = 'ontario-search-input-field';
289
+ return (
290
+ <form
291
+ name="searchForm"
292
+ id="ontario-search-form-container"
293
+ class="ontario-search__container ontario-columns ontario-small-10 ontario-medium-offset-3 ontario-medium-6 ontario-large-offset-0 ontario-large-6"
294
+ novalidate
295
+ >
296
+ {this.captionState.getCaption(searchInputFieldId, false, true) /* Note the _required_ text is disabled */}
297
+ {this.internalHintText && (
298
+ <ontario-hint-text
299
+ hint={this.internalHintText.hint}
300
+ hintContentType={this.internalHintText.hintContentType}
301
+ ref={(el) => (this.hintTextRef = el)}
302
+ ></ontario-hint-text>
303
+ )}
304
+
305
+ <div class="ontario-search__input-container">
306
+ <Input
307
+ aria-describedBy={this.hintTextId}
308
+ type="search"
309
+ name="search"
310
+ id={searchInputFieldId}
311
+ autoComplete="off"
312
+ aria-autocomplete="none"
313
+ className="ontario-search__input ontario-input"
314
+ required={true}
315
+ ref={(el) => (this.inputFieldRef = el)}
316
+ onInput={(e) => this.handleEvent(e, EventType.Input)}
317
+ onChange={(e) => this.handleEvent(e, EventType.Change)}
318
+ onBlur={(e) => this.handleEvent(e, EventType.Blur)}
319
+ onFocus={(e) => this.handleEvent(e, EventType.Focus)}
320
+ value={this.getValue()}
321
+ ></Input>
322
+ <Input
323
+ className="ontario-search__reset"
324
+ id="ontario-search-reset"
325
+ type="reset"
326
+ value=""
327
+ onClick={() => this.handleFocus()}
328
+ ></Input>
329
+ <button
330
+ class="ontario-search__submit"
331
+ type="submit"
332
+ id="ontario-search-box__submit"
333
+ onClick={(e) => this.handleSearch(e)}
334
+ >
335
+ <span innerHTML={OntarioIconSearch} />
336
+ </button>
337
+ </div>
338
+ </form>
339
+ );
340
+ }
341
+ }
@@ -0,0 +1,132 @@
1
+ import { OntarioSearchBox } from '@ongov/ontario-design-system-component-library-react';
2
+
3
+ # ontario-search-box
4
+
5
+ Use a search box to let users complete keyword-based searches.
6
+
7
+ ## User guidance
8
+
9
+ Please refer to the [Ontario Design System](https://designsystem.ontario.ca/components/detail/search-box.html) for current documentation guidance.
10
+
11
+ ## Configuration
12
+
13
+ Once the component package has been installed (see Ontario Design System Component Library for installation instructions), the search box component can be added directly into the project's code, and can be customized by updating the properties outlined [here](#properties). Additional information on custom types for header properties are outlined [here](#custom-property-types). Please see the [examples](#examples) below for how to configure the component.
14
+
15
+ ## Example
16
+
17
+ ### Search box with caption
18
+
19
+ ```html
20
+ <ontario-search-box id="ontario-search-box" caption="Search the directory"></ontario-search-box>
21
+ ```
22
+
23
+ <div>
24
+ <OntarioSearchBox id="ontario-search-box" caption="Search the directory"></OntarioSearchBox>
25
+ </div>
26
+
27
+ ### Handling searching
28
+
29
+ The `<ontario-search-box>` provides two ways to handle searching.
30
+
31
+ #### The `performSearch()` function
32
+
33
+ The `performSearch()` function allows for custom logic to be executed when the search box is submitted for searching. When the search box calls this function internally it will pass to it a string that is the value of the search field. This function is [asynchronous](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) and should return a [`Promise<void>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
34
+
35
+ ##### Example
36
+
37
+ The following example registers a simple function on `window` `load` that assigns a custom function to the search box's `performSearch()` function to handle the application specific search logic.
38
+
39
+ ```html
40
+ <script>
41
+ window.addEventListener('load', () => {
42
+ console.log('Loaded Search Box Event Listener');
43
+
44
+ const searchBox = document.getElementById('ontario-search-box');
45
+ searchBox.performSearch = async (value) => {
46
+ console.log('Performing search with value:', value);
47
+ };
48
+ });
49
+ </script>
50
+ ```
51
+
52
+ #### Using the `searchOnSubmit` function
53
+
54
+ As an alternative to using a custom `performSearch()` function the search box also emits an event, `searchOnSubmit` that can be listened to to trigger any custom search logic that is needed. This allows for applications to listen for a search being performed and act accordingly. The value of the search box will be passed via the [`CustomEvent` `detail`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#detail) property.
55
+
56
+ ##### Example
57
+
58
+ The following example registers a simple function on `window` `load` that adds an event listener to the search box listening for the `searchOnSubmit` event and outputs the value of the `detail` property.
59
+
60
+ ```html
61
+ <script>
62
+ window.addEventListener('load', () => {
63
+ console.log('Loaded Search Box Event Listener');
64
+
65
+ const searchBox = document.getElementById('ontario-search-box');
66
+ searchBox.addEventListener('searchOnSubmit', (event) => {
67
+ console.log('Search Event Detail:', event.detail);
68
+ });
69
+ });
70
+ </script>
71
+ ```
72
+
73
+ ## Custom property types
74
+
75
+ ### caption
76
+
77
+ The `caption` property is used to render the label for the ontario-input. It can be passed either a string or an object. If no `captionType` needs to be specified, it can be passed as a string.
78
+
79
+ ```html
80
+ caption='{ "captionText": "Input label", "captionType": "large" }'
81
+ ```
82
+
83
+ | Property name | Type | Description |
84
+ | ------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
85
+ | `captionText` | `string` | Text to display as the input question |
86
+ | `captionType` | `"default" \| "large"\| "heading"` | The type of label to display for the input question. This is optional, and if no information is provided, it will default to the `default` type. |
87
+
88
+ <!-- Auto Generated Below -->
89
+
90
+ ## Properties
91
+
92
+ | Property | Attribute | Description | Type | Default |
93
+ | ---------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | ----------- |
94
+ | `caption` | `caption` | The text to display as the input label | `Caption \| string` | `undefined` |
95
+ | `customOnBlur` | -- | Used to add a custom function to the input onBlur event. | `((event: Event) => void) \| undefined` | `undefined` |
96
+ | `customOnChange` | -- | Used to add a custom function to the input onChange event. | `((event: Event) => void) \| undefined` | `undefined` |
97
+ | `customOnFocus` | -- | Used to add a custom function to the input onFocus event. | `((event: Event) => void) \| undefined` | `undefined` |
98
+ | `customOnInput` | -- | Used to add a custom function to the input onInput event. | `((event: Event) => void) \| undefined` | `undefined` |
99
+ | `elementId` | `element-id` | The unique identifier of the search-box component. This is optional - if no ID is passed, one will be generated. | `string \| undefined` | `undefined` |
100
+ | `hintText` | `hint-text` | Used to include the ontario-hint-text component for the search-box. This is optional. | `Hint \| string \| undefined` | `undefined` |
101
+ | `language` | `language` | The language of the component. This is used for translations. If none is passed, it will default to English. | `"en" \| "fr" \| undefined` | `'en'` |
102
+ | `performSearch` | -- | This Function to perform a search operation. This function will be called when the search submit button is triggered. The value argument is used for as search term to use for the search operation. This parameter is optional. The performSearch prop can be set dynamically using JavaScript, allowing you to define custom search functionality when the search form is submitted. | `((value?: string \| undefined) => Promise<void>) \| undefined` | `undefined` |
103
+ | `required` | `required` | This is used to determine whether the dropdown list is required or not. This prop gets passed to the InputCaption utility to display either an optional or required flag in the label. If no prop is set, it will default to false (optional). | `boolean \| undefined` | `false` |
104
+ | `value` | `value` | The value of the search term. This is optional. | `string \| undefined` | `undefined` |
105
+
106
+ ## Events
107
+
108
+ | Event | Description | Type |
109
+ | ---------------- | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
110
+ | `inputOnBlur` | Emitted when a keyboard input event occurs when an input has lost focus. | `CustomEvent<InputInteractionEvent & { focused: boolean; }>` |
111
+ | `inputOnChange` | Emitted when a keyboard input or mouse event occurs when an input has been changed. | `CustomEvent<{ id?: string \| undefined; value?: string \| undefined; }>` |
112
+ | `inputOnFocus` | Emitted when a keyboard input event occurs when an input has gained focus. | `CustomEvent<InputInteractionEvent & { focused: boolean; }>` |
113
+ | `inputOnInput` | Emitted when a input  occurs when an input has been changed. | `CustomEvent<InputInteractionEvent & { inputType?: string \| undefined; }>` |
114
+ | `searchOnSubmit` | Emitted when the search is submitted. Below is an example on how to hook into the event to get the event details. | `CustomEvent<string>` |
115
+
116
+ ## Dependencies
117
+
118
+ ### Depends on
119
+
120
+ - [ontario-hint-text](../ontario-hint-text)
121
+
122
+ ### Graph
123
+
124
+ ```mermaid
125
+ graph TD;
126
+ ontario-search-box --> ontario-hint-text
127
+ style ontario-search-box fill:#f9f,stroke:#333,stroke-width:4px
128
+ ```
129
+
130
+ ---
131
+
132
+ _Built with [StencilJS](https://stenciljs.com/)_
@@ -0,0 +1,35 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`ontario-search-box should render a default search box element 1`] = `
4
+ <ontario-search-box>
5
+ <mock:shadow-root>
6
+ <form class="ontario-columns ontario-large-6 ontario-large-offset-0 ontario-medium-6 ontario-medium-offset-3 ontario-search__container ontario-small-10" id="ontario-search-form-container" name="searchForm" novalidate="">
7
+ <label class="ontario-label" htmlfor="ontario-search-input-field"></label>
8
+ <div class="ontario-search__input-container">
9
+ <input aria-autocomplete="none" autocomplete="off" class="ontario-input ontario-search__input" id="ontario-search-input-field" name="search" required="" type="search" value="">
10
+ <input class="ontario-search__reset" id="ontario-search-reset" type="reset" value="">
11
+ <button class="ontario-search__submit" id="ontario-search-box__submit" type="submit">
12
+ <span></span>
13
+ </button>
14
+ </div>
15
+ </form>
16
+ </mock:shadow-root>
17
+ </ontario-search-box>
18
+ `;
19
+
20
+ exports[`ontario-search-box should render the expected html 1`] = `
21
+ <ontario-search-box class="hydrated" id="ontario-search-box">
22
+ <mock:shadow-root>
23
+ <form class="ontario-columns ontario-large-6 ontario-large-offset-0 ontario-medium-6 ontario-medium-offset-3 ontario-search__container ontario-small-10" id="ontario-search-form-container" name="searchForm" novalidate="">
24
+ <label class="ontario-label" htmlfor="ontario-search-input-field"></label>
25
+ <div class="ontario-search__input-container">
26
+ <input aria-autocomplete="none" autocomplete="off" class="ontario-input ontario-search__input" id="ontario-search-input-field" name="search" required="" type="search" value="">
27
+ <input class="ontario-search__reset" id="ontario-search-reset" type="reset" value="">
28
+ <button class="ontario-search__submit" id="ontario-search-box__submit" type="submit">
29
+ <span></span>
30
+ </button>
31
+ </div>
32
+ </form>
33
+ </mock:shadow-root>
34
+ </ontario-search-box>
35
+ `;
@@ -0,0 +1,21 @@
1
+ import { newE2EPage } from '@stencil/core/testing';
2
+
3
+ describe('ontario-search-box', () => {
4
+ //checks if the component has hydrated class
5
+ it('renders', async () => {
6
+ const page = await newE2EPage();
7
+ await page.setContent(`<ontario-search-box></ontario-search-box>`);
8
+ const element = await page.find('ontario-search-box');
9
+ expect(element).toHaveClass('hydrated');
10
+ });
11
+
12
+ it('checks the onclick event', async () => {
13
+ const page = await newE2EPage();
14
+ await page.setContent('<ontario-search-box></ontario-search-box>');
15
+ const changedEvent = await page.spyOnEvent('click');
16
+ const component = await page.find('ontario-search-box >>> #ontario-search-submit');
17
+ component.click();
18
+ await page.waitForChanges();
19
+ expect(changedEvent).toHaveReceivedEventTimes(1);
20
+ });
21
+ });
@@ -0,0 +1,22 @@
1
+ import { newSpecPage } from '@stencil/core/testing';
2
+ import { OntarioSearchBox } from '../ontario-search-box';
3
+
4
+ describe('ontario-search-box', () => {
5
+ it('should render the expected html', async () => {
6
+ const page = await newSpecPage({
7
+ components: [OntarioSearchBox],
8
+ html: `<ontario-search-box id="ontario-search-box" class="hydrated"></ontario-search-box>`,
9
+ });
10
+
11
+ expect(page.root).toMatchSnapshot();
12
+ });
13
+
14
+ it('should render a default search box element', async () => {
15
+ const page = await newSpecPage({
16
+ components: [OntarioSearchBox],
17
+ html: `<ontario-search-box></ontario-search-box>`,
18
+ });
19
+
20
+ expect(page.root).toMatchSnapshot();
21
+ });
22
+ });