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

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 (108) hide show
  1. package/dist/cjs/index-88d5cf20.js +2 -2
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/{ontario-accordion_43.cjs.entry.js → ontario-accordion_44.cjs.entry.js} +339 -78
  4. package/dist/cjs/ontario-accordion_44.cjs.entry.js.map +1 -0
  5. package/dist/cjs/ontario-design-system-components.cjs.js +1 -1
  6. package/dist/collection/collection-manifest.json +1 -0
  7. package/dist/collection/components/ontario-card/ontario-card-types.js +29 -2
  8. package/dist/collection/components/ontario-card/ontario-card-types.js.map +1 -1
  9. package/dist/collection/components/ontario-card/ontario-card.css +252 -34
  10. package/dist/collection/components/ontario-card/ontario-card.js +102 -78
  11. package/dist/collection/components/ontario-card/ontario-card.js.map +1 -1
  12. package/dist/collection/components/ontario-card/test/ontario-cards.spec.js +23 -13
  13. package/dist/collection/components/ontario-card/test/ontario-cards.spec.js.map +1 -1
  14. package/dist/collection/components/ontario-header/service-ontario-header.css +0 -3
  15. package/dist/collection/components/ontario-search-box/assets/ontario-icon-close.svg +1 -0
  16. package/dist/collection/components/ontario-search-box/assets/ontario-logo--mobile.svg +6 -0
  17. package/dist/collection/components/ontario-search-box/ontario-search-box.css +823 -0
  18. package/dist/collection/components/ontario-search-box/ontario-search-box.js +584 -0
  19. package/dist/collection/components/ontario-search-box/ontario-search-box.js.map +1 -0
  20. package/dist/collection/components/ontario-search-box/test/ontario-search-box.e2e.js +20 -0
  21. package/dist/collection/components/ontario-search-box/test/ontario-search-box.e2e.js.map +1 -0
  22. package/dist/collection/components/ontario-search-box/test/ontario-search-box.spec.js +19 -0
  23. package/dist/collection/components/ontario-search-box/test/ontario-search-box.spec.js.map +1 -0
  24. package/dist/collection/components/ontario-step-indicator/ontario-step-indicator.js +5 -5
  25. package/dist/collection/components/ontario-table/ontario-table.js +5 -5
  26. package/dist/collection/components/ontario-textarea/ontario-textarea.js +3 -3
  27. package/dist/collection/utils/common/input/input.js +3 -0
  28. package/dist/collection/utils/common/input/input.js.map +1 -1
  29. package/dist/collection/utils/common/input-caption/input-caption.js +5 -3
  30. package/dist/collection/utils/common/input-caption/input-caption.js.map +1 -1
  31. package/dist/components/error-message.js +1 -324
  32. package/dist/components/error-message.js.map +1 -1
  33. package/dist/components/event-handler.js +330 -0
  34. package/dist/components/event-handler.js.map +1 -0
  35. package/dist/components/input.js +3 -0
  36. package/dist/components/input.js.map +1 -1
  37. package/dist/components/ontario-card.js +116 -64
  38. package/dist/components/ontario-card.js.map +1 -1
  39. package/dist/components/ontario-checkboxes.js +2 -1
  40. package/dist/components/ontario-checkboxes.js.map +1 -1
  41. package/dist/components/ontario-date-input.js +2 -1
  42. package/dist/components/ontario-date-input.js.map +1 -1
  43. package/dist/components/ontario-dropdown-list.js +2 -1
  44. package/dist/components/ontario-dropdown-list.js.map +1 -1
  45. package/dist/components/ontario-header.js +2 -4
  46. package/dist/components/ontario-header.js.map +1 -1
  47. package/dist/components/ontario-icon-search2.js +6 -0
  48. package/dist/components/ontario-icon-search2.js.map +1 -0
  49. package/dist/components/ontario-input.js +2 -1
  50. package/dist/components/ontario-input.js.map +1 -1
  51. package/dist/components/ontario-radio-buttons.js +2 -1
  52. package/dist/components/ontario-radio-buttons.js.map +1 -1
  53. package/dist/components/ontario-search-box.d.ts +11 -0
  54. package/dist/components/ontario-search-box.js +269 -0
  55. package/dist/components/ontario-search-box.js.map +1 -0
  56. package/dist/components/ontario-step-indicator.js +5 -5
  57. package/dist/components/ontario-table.js +5 -5
  58. package/dist/components/ontario-textarea.js +5 -4
  59. package/dist/components/ontario-textarea.js.map +1 -1
  60. package/dist/esm/index-603026f7.js +2 -2
  61. package/dist/esm/loader.js +1 -1
  62. package/dist/esm/{ontario-accordion_43.entry.js → ontario-accordion_44.entry.js} +339 -78
  63. package/dist/esm/ontario-accordion_44.entry.js.map +1 -0
  64. package/dist/esm/ontario-design-system-components.js +1 -1
  65. package/dist/ontario-design-system-components/ontario-design-system-components.esm.js +1 -1
  66. package/dist/ontario-design-system-components/ontario-design-system-components.esm.js.map +1 -1
  67. package/dist/ontario-design-system-components/{p-abe58ec9.entry.js → p-9c3a1be9.entry.js} +1925 -1728
  68. package/dist/ontario-design-system-components/p-9c3a1be9.entry.js.map +1 -0
  69. package/dist/types/components/ontario-card/ontario-card-types.d.ts +4 -4
  70. package/dist/types/components/ontario-card/ontario-card.d.ts +40 -29
  71. package/dist/types/components/ontario-search-box/ontario-search-box.d.ts +180 -0
  72. package/dist/types/components.d.ts +199 -16
  73. package/dist/types/utils/common/input/input.d.ts +2 -1
  74. package/dist/types/utils/common/input-caption/input-caption.d.ts +7 -1
  75. package/package.json +2 -2
  76. package/src/components/ontario-card/ontario-card-types.tsx +33 -4
  77. package/src/components/ontario-card/ontario-card.scss +54 -40
  78. package/src/components/ontario-card/ontario-card.tsx +94 -68
  79. package/src/components/ontario-card/readme.md +57 -27
  80. package/src/components/ontario-card/test/__snapshots__/ontario-cards.spec.tsx.snap +66 -0
  81. package/src/components/ontario-card/test/ontario-cards.spec.tsx +27 -13
  82. package/src/components/ontario-card-collection/readme.md +13 -13
  83. package/src/components/ontario-checkbox/ontario-checkboxes.scss +0 -1
  84. package/src/components/ontario-header/service-ontario-header.scss +0 -4
  85. package/src/components/ontario-hint-text/readme.md +2 -0
  86. package/src/components/ontario-radio-buttons/ontario-radio-buttons.scss +0 -1
  87. package/src/components/ontario-search-box/assets/ontario-icon-close.svg +1 -0
  88. package/src/components/ontario-search-box/assets/ontario-logo--mobile.svg +6 -0
  89. package/src/components/ontario-search-box/ontario-search-box.scss +141 -0
  90. package/src/components/ontario-search-box/ontario-search-box.tsx +341 -0
  91. package/src/components/ontario-search-box/readme.md +132 -0
  92. package/src/components/ontario-search-box/test/__snapshots__/ontario-search-box.spec.tsx.snap +35 -0
  93. package/src/components/ontario-search-box/test/ontario-search-box.e2e.ts +21 -0
  94. package/src/components/ontario-search-box/test/ontario-search-box.spec.tsx +22 -0
  95. package/src/components.d.ts +199 -16
  96. package/src/index.html +287 -52
  97. package/src/utils/common/input/input.tsx +4 -1
  98. package/src/utils/common/input-caption/input-caption.tsx +9 -3
  99. package/www/build/ontario-design-system-components.esm.js +1 -1
  100. package/www/build/ontario-design-system-components.esm.js.map +1 -1
  101. package/www/build/{p-fdc9ab6d.js → p-84035ac3.js} +1 -1
  102. package/www/build/{p-abe58ec9.entry.js → p-9c3a1be9.entry.js} +1925 -1728
  103. package/www/build/p-9c3a1be9.entry.js.map +1 -0
  104. package/www/index.html +261 -52
  105. package/dist/cjs/ontario-accordion_43.cjs.entry.js.map +0 -1
  106. package/dist/esm/ontario-accordion_43.entry.js.map +0 -1
  107. package/dist/ontario-design-system-components/p-abe58ec9.entry.js.map +0 -1
  108. package/www/build/p-abe58ec9.entry.js.map +0 -1
@@ -7,18 +7,32 @@ describe('ontario-card', () => {
7
7
  components: [OntarioCard],
8
8
  html: `<ontario-card></ontario-card>`,
9
9
  });
10
- expect(page.root).toEqualHtml(`
11
- <ontario-card>
12
- <mock:shadow-root>
13
- <li class="ontario-card ontario-card__card-type--basic ontario-card__header-type--default ontario-card__description-false">
14
- <div class="ontario-card__text-container">
15
- <h2 class="ontario-card__heading">
16
- <a href="#"></a>
17
- </h2>
18
- </div>
19
- </li>
20
- </mock:shadow-root>
21
- </ontario-card>
22
- `);
10
+ expect(page.root).toMatchSnapshot();
23
11
  });
12
+
13
+ it('should render a label', async () => {
14
+ const page = await newSpecPage({
15
+ components: [OntarioCard],
16
+ html: `<ontario-card label="Card Title 1"></ontario-card>`,
17
+ });
18
+ expect(page.root).toMatchSnapshot();
19
+ });
20
+
21
+ it('should render a header colour on the label', async () => {
22
+ const page = await newSpecPage({
23
+ components: [OntarioCard],
24
+ html: `<ontario-card label="Card Title 1" header-colour="sky"></ontario-card>`,
25
+ });
26
+ expect(page.root).toMatchSnapshot();
27
+ });
28
+
29
+ it('should render a description', async () => {
30
+ const page = await newSpecPage({
31
+ components: [OntarioCard],
32
+ html: `<ontario-card description="Lorem ipsum"></ontario-card>`,
33
+ });
34
+ expect(page.root).toMatchSnapshot();
35
+ });
36
+
37
+ // Don't think we can test images unless we point to a local path
24
38
  });
@@ -20,9 +20,9 @@ Example of a bare-bones `ontario-card-collection` component, with a `cardsPerRow
20
20
  ```html
21
21
  <ontario-card-collection cards-per-row="2">
22
22
  <ontario-card
23
- card-type="horizontal"
23
+ layout="horizontal"
24
24
  label="Card Title 1"
25
- image="https://picsum.photos/200/300"
25
+ image="https://picsum.photos/300/225"
26
26
  card-link="https://google.ca"
27
27
  horizontal-image-position-type="left"
28
28
  horizontal-image-size-type="one-fourth"
@@ -30,9 +30,9 @@ Example of a bare-bones `ontario-card-collection` component, with a `cardsPerRow
30
30
  >
31
31
  </ontario-card>
32
32
  <ontario-card
33
- card-type="horizontal"
33
+ layout="horizontal"
34
34
  label="Card Title 2"
35
- image="https://picsum.photos/200/300"
35
+ image="https://picsum.photos/300/225"
36
36
  horizontal-image-position-type="left"
37
37
  horizontal-image-size-type="one-fourth"
38
38
  description="Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum"
@@ -43,21 +43,21 @@ Example of a bare-bones `ontario-card-collection` component, with a `cardsPerRow
43
43
 
44
44
  <OntarioCardCollection cards-per-row="2">
45
45
  <OntarioCard
46
- card-type="horizontal"
46
+ layout="horizontal"
47
47
  label="Card Title 1"
48
- image="https://picsum.photos/200/300"
49
- card-link="https://google.ca"
50
- horizontal-image-position-type="left"
51
- horizontal-image-size-type="one-fourth"
48
+ image="https://picsum.photos/300/225"
49
+ cardLink="https://google.ca"
50
+ horizontalImagePositionType="left"
51
+ horizontalImageSizeType="one-fourth"
52
52
  description="Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum"
53
53
  >
54
54
  </OntarioCard>
55
55
  <OntarioCard
56
- card-type="horizontal"
56
+ layout="horizontal"
57
57
  label="Card Title 2"
58
- image="https://picsum.photos/200/300"
59
- horizontal-image-position-type="left"
60
- horizontal-image-size-type="one-fourth"
58
+ image="https://picsum.photos/300/225"
59
+ horizontalImagePositionType="left"
60
+ horizontalImageSizeType="one-fourth"
61
61
  description="Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum"
62
62
  >
63
63
  </OntarioCard>
@@ -16,7 +16,6 @@ $ontario-checkboxes-size: globalFunctions.px-to-rem(28);
16
16
  $ontario-checkboxes-size-mobile: globalFunctions.px-to-rem(32);
17
17
  $ontario-checkbox-border-size: globalFunctions.px-to-rem(2);
18
18
  $ontario-checkbox-box-shadow-outline: globalFunctions.px-to-rem(4);
19
- $ontario-input-border-width: 0.125rem;
20
19
 
21
20
  :host {
22
21
  --checkbox-bg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M0 2.667C0 1.194 1.194 0 2.667 0h18.667C22.806 0 24 1.194 24 2.667v18.667C24 22.806 22.806 24 21.333 24H2.667C1.194 24 0 22.806 0 21.333V2.667z' fill='%231a1a1a'/%3E%3Cpath d='M2.667 12.616l6.667 6.718 12-12.092-1.88-1.908L9.333 15.53l-4.787-4.8-1.88 1.894z' fill='%23fff'/%3E%3C/svg%3E");
@@ -57,10 +57,6 @@
57
57
 
58
58
  .ontario-service-subheader .ontario-header-button {
59
59
  display: flex;
60
-
61
- &:last-of-type {
62
- display: none;
63
- }
64
60
  }
65
61
 
66
62
  .ontario-service-subheader .ontario-header-button {
@@ -67,6 +67,7 @@ Promise<string | undefined>
67
67
  - [ontario-dropdown-list](../ontario-dropdown-list)
68
68
  - [ontario-input](../ontario-input)
69
69
  - [ontario-radio-buttons](../ontario-radio-buttons)
70
+ - [ontario-search-box](../ontario-search-box)
70
71
  - [ontario-textarea](../ontario-textarea)
71
72
 
72
73
  ### Graph
@@ -77,6 +78,7 @@ graph TD;
77
78
  ontario-dropdown-list --> ontario-hint-text
78
79
  ontario-input --> ontario-hint-text
79
80
  ontario-radio-buttons --> ontario-hint-text
81
+ ontario-search-box --> ontario-hint-text
80
82
  ontario-textarea --> ontario-hint-text
81
83
  style ontario-hint-text fill:#f9f,stroke:#333,stroke-width:4px
82
84
  ```
@@ -19,7 +19,6 @@
19
19
  $ontario-radios-size: 32px;
20
20
  $ontario-radios-size-mobile: 36px;
21
21
  $ontario-input-offset: math.div((globalVariables.$touch-target-size - $ontario-radios-size), 2);
22
- $ontario-input-border-width: 0.125rem;
23
22
 
24
23
  .ontario-radios__item {
25
24
  position: relative;
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"><path d="M19 6.4L17.6 5 12 10.6 6.4 5 5 6.4l5.6 5.6L5 17.6 6.4 19l5.6-5.6 5.6 5.6 1.4-1.4-5.6-5.6L19 6.4z" fill="#000"/></svg>
@@ -0,0 +1,6 @@
1
+ <svg width="46" height="46" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 46 46" fill="none" xmlns:v="https://vecta.io/nano" tabindex="-1">
2
+ <path d="M23 0C7.36 0 0 7.36 0 23s7.36 23 23 23 23-7.36 23-23S38.64 0 23 0" fill="#fff" />
3
+ <path fill-rule="evenodd"
4
+ d="M23 13.223c4.728-3.178 10.58-3.613 15.69-1.153l.18.128-.026.18a16.08 16.08 0 0 1-2.07 6.765c-1.405 2.41-3.4 4.408-5.8 5.79h-.025a15.71 15.71 0 0 0-.365.191c-.188.1-.38.203-.58.296.383 5.69-2.172 10.994-6.85 14.197L23 39.72l-.153-.102a15.76 15.76 0 0 1-4.805-5.176 16.12 16.12 0 0 1-2.095-7.944v-.026c0-.333.025-.692.05-1.05-5.086-2.51-8.382-7.38-8.817-13.043l-.026-.18.153-.077c2.147-1.05 4.523-1.59 6.874-1.59 2.786 0 5.494.743 7.897 2.127h.026a17.21 17.21 0 0 1 .895.564zm5.93 8.56c1.763-1.025 3.27-2.46 4.37-4.33.51-.897.894-1.82 1.176-2.69-2.888-.666-5.8-.23-8.433 1.204.23.307.383.64.537 1.076s.18 1.025.05 1.512c-.05.205-.153.4-.256.615h0c-.51.87-1.584 1.512-2.913 1.922.51-1.59-.307-2.998-1.33-3.895-.51-.46-1.1-.846-1.687-1.204a12.29 12.29 0 0 0-5.929-1.614 12.52 12.52 0 0 0-2.964.359c.894 2.844 2.71 5.15 5.265 6.714.153-.36.358-.64.664-1s.792-.666 1.278-.794a2.94 2.94 0 0 1 .664-.077c.997 0 2.096.615 3.118 1.563-1.6.36-2.428 1.768-2.683 3.1-.128.692-.204 1.384-.204 2.076 0 2.024.486 4.075 1.56 5.945.486.87 1.125 1.69 1.79 2.383 2.02-2.204 3.092-4.946 3.17-7.944-.41.05-.74 0-1.2-.077s-.97-.384-1.33-.718c-.153-.154-.307-.333-.41-.538-.51-.897-.51-2.153-.204-3.51 1.124 1.23 2.734 1.256 4.012.794a10.52 10.52 0 0 0 1.891-.871z"
5
+ fill="#000" />
6
+ </svg>
@@ -0,0 +1,141 @@
1
+ @use 'sass:math';
2
+ @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/1-variables/global.variables' as globalVariables;
3
+ @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/1-variables/spacing.variables' as spacing;
4
+ @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/1-variables/colours.variables' as colours;
5
+ @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/1-variables/breakpoints.variables' as breakpoints;
6
+ @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/1-variables/typography.variables' as typography;
7
+ @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/1-variables/line-heights.variables' as lineheight;
8
+ @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/1-variables/font-weights.variables' as fontWeights;
9
+ @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/2-tools/functions/global.functions' as globalFunctions;
10
+ @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/2-tools/placeholder/focus.placeholders' as
11
+ focusPlaceholders;
12
+ @use '@ongov/ontario-design-system-global-styles/dist/styles/scss/4-elements/_global.elements.scss';
13
+ @use '../../styles/form.scss';
14
+
15
+ $ontario-input-height: globalFunctions.px-to-rem(48);
16
+ $ontario-search-icon-size: 2rem;
17
+ $ontario-reset-icon-size: 1.5rem;
18
+ $ontario-search-button-width: 5rem;
19
+ $ontario-search-button-width--mobile: 3rem;
20
+ $ontario-search-input-padding: 8.5rem;
21
+ $ontario-search-input-padding--mobile: 7.75rem;
22
+ $ontario-search-desktop-width: 34rem;
23
+ $ontario-search-mobile-width: 20.5rem;
24
+
25
+ .ontario-search__container {
26
+ max-width: $ontario-search-desktop-width;
27
+ margin-bottom: spacing.$spacing-7;
28
+ }
29
+
30
+ .ontario-search__input-container {
31
+ position: relative;
32
+ }
33
+
34
+ .ontario-search__input.ontario-input {
35
+ border: 2px solid colours.$ontario-colour-black;
36
+ margin-bottom: spacing.$spacing-0;
37
+ height: $ontario-input-height;
38
+ padding-left: spacing.$spacing-3;
39
+ padding-right: $ontario-search-input-padding;
40
+ width: 100%;
41
+
42
+ &:invalid + input[type='reset'] {
43
+ display: none;
44
+ }
45
+
46
+ &:focus {
47
+ @extend %ontario-focus;
48
+ }
49
+ }
50
+
51
+ input[type='reset'].ontario-search__reset {
52
+ position: absolute;
53
+ display: flex;
54
+ align-items: center;
55
+ top: spacing.$spacing-3;
56
+ right: $ontario-search-button-width + spacing.$spacing-4;
57
+ height: $ontario-reset-icon-size;
58
+ width: $ontario-reset-icon-size;
59
+ color: colours.$ontario-colour-black;
60
+ margin: spacing.$spacing-0;
61
+ padding: spacing.$spacing-1;
62
+ background-size: $ontario-reset-icon-size;
63
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PHBhdGggZD0iTTE5IDYuNEwxNy42IDUgMTIgMTAuNiA2LjQgNSA1IDYuNGw1LjYgNS42TDUgMTcuNiA2LjQgMTlsNS42LTUuNiA1LjYgNS42IDEuNC0xLjQtNS42LTUuNkwxOSA2LjR6IiBmaWxsPSIjMDAwIi8+PC9zdmc+);
64
+ background-position: center center;
65
+ background-repeat: no-repeat;
66
+ background-color: transparent;
67
+ outline: none;
68
+ border: none;
69
+ cursor: pointer;
70
+
71
+ &:focus {
72
+ box-shadow: inset 0 0 0 globalVariables.$global-radius colours.$ontario-colour-focus;
73
+ }
74
+
75
+ @media screen and (max-width: breakpoints.$small-breakpoint) {
76
+ right: $ontario-search-button-width--mobile + spacing.$spacing-7;
77
+ }
78
+ }
79
+
80
+ .ontario-search__submit {
81
+ border: 0;
82
+ border-radius: 0 3px 3px 0;
83
+ background-color: colours.$ontario-colour-link;
84
+ color: colours.$ontario-colour-black;
85
+
86
+ display: flex;
87
+ justify-content: center;
88
+ align-items: center;
89
+
90
+ font-family: typography.$ontario-font-open-sans;
91
+ font-weight: fontWeights.$ontario-font-weights-semi-bold;
92
+ font-size: 1.125rem;
93
+ width: $ontario-search-button-width;
94
+ line-height: lineheight.$ontario-line-height-8;
95
+
96
+ position: absolute;
97
+ right: spacing.$spacing-0;
98
+ bottom: spacing.$spacing-0;
99
+ top: spacing.$spacing-0;
100
+ cursor: pointer;
101
+
102
+ &:hover {
103
+ background-color: colours.$ontario-colour-link--hover;
104
+ color: colours.$ontario-colour-white;
105
+ }
106
+
107
+ &:focus {
108
+ outline: none;
109
+ box-shadow: 0 0 0 globalVariables.$global-radius colours.$ontario-colour-focus;
110
+ background-color: colours.$ontario-colour-link--hover;
111
+ color: colours.$ontario-colour-white;
112
+ }
113
+
114
+ &:active {
115
+ background-color: colours.$ontario-colour-link--active;
116
+ color: colours.$ontario-colour-white;
117
+ }
118
+
119
+ svg {
120
+ fill: colours.$ontario-colour-white;
121
+ margin-right: spacing.$spacing-0;
122
+ margin-bottom: spacing.$spacing-0;
123
+ width: $ontario-search-icon-size;
124
+ height: $ontario-search-icon-size;
125
+ display: inline-block;
126
+ vertical-align: middle;
127
+ overflow: hidden;
128
+ }
129
+
130
+ @media screen and (max-width: breakpoints.$small-breakpoint) {
131
+ width: $ontario-search-button-width--mobile;
132
+ }
133
+ }
134
+
135
+ // remove default cancel button for input with type="search"
136
+ input[type='search'].ontario-search__input::-webkit-search-decoration,
137
+ input[type='search'].ontario-search__input::-webkit-search-cancel-button,
138
+ input[type='search'].ontario-search__input::-webkit-search-results-button,
139
+ input[type='search'].ontario-search__input::-webkit-search-results-decoration {
140
+ -webkit-appearance: none;
141
+ }
@@ -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
+ }