@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.
- package/dist/cjs/index-88d5cf20.js +2 -2
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{ontario-accordion_43.cjs.entry.js → ontario-accordion_44.cjs.entry.js} +339 -78
- package/dist/cjs/ontario-accordion_44.cjs.entry.js.map +1 -0
- package/dist/cjs/ontario-design-system-components.cjs.js +1 -1
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/ontario-card/ontario-card-types.js +29 -2
- package/dist/collection/components/ontario-card/ontario-card-types.js.map +1 -1
- package/dist/collection/components/ontario-card/ontario-card.css +252 -34
- package/dist/collection/components/ontario-card/ontario-card.js +102 -78
- package/dist/collection/components/ontario-card/ontario-card.js.map +1 -1
- package/dist/collection/components/ontario-card/test/ontario-cards.spec.js +23 -13
- package/dist/collection/components/ontario-card/test/ontario-cards.spec.js.map +1 -1
- package/dist/collection/components/ontario-header/service-ontario-header.css +0 -3
- package/dist/collection/components/ontario-search-box/assets/ontario-icon-close.svg +1 -0
- package/dist/collection/components/ontario-search-box/assets/ontario-logo--mobile.svg +6 -0
- package/dist/collection/components/ontario-search-box/ontario-search-box.css +823 -0
- package/dist/collection/components/ontario-search-box/ontario-search-box.js +584 -0
- package/dist/collection/components/ontario-search-box/ontario-search-box.js.map +1 -0
- package/dist/collection/components/ontario-search-box/test/ontario-search-box.e2e.js +20 -0
- package/dist/collection/components/ontario-search-box/test/ontario-search-box.e2e.js.map +1 -0
- package/dist/collection/components/ontario-search-box/test/ontario-search-box.spec.js +19 -0
- package/dist/collection/components/ontario-search-box/test/ontario-search-box.spec.js.map +1 -0
- package/dist/collection/components/ontario-step-indicator/ontario-step-indicator.js +5 -5
- package/dist/collection/components/ontario-table/ontario-table.js +5 -5
- package/dist/collection/components/ontario-textarea/ontario-textarea.js +3 -3
- package/dist/collection/utils/common/input/input.js +3 -0
- package/dist/collection/utils/common/input/input.js.map +1 -1
- package/dist/collection/utils/common/input-caption/input-caption.js +5 -3
- package/dist/collection/utils/common/input-caption/input-caption.js.map +1 -1
- package/dist/components/error-message.js +1 -324
- package/dist/components/error-message.js.map +1 -1
- package/dist/components/event-handler.js +330 -0
- package/dist/components/event-handler.js.map +1 -0
- package/dist/components/input.js +3 -0
- package/dist/components/input.js.map +1 -1
- package/dist/components/ontario-card.js +116 -64
- package/dist/components/ontario-card.js.map +1 -1
- package/dist/components/ontario-checkboxes.js +2 -1
- package/dist/components/ontario-checkboxes.js.map +1 -1
- package/dist/components/ontario-date-input.js +2 -1
- package/dist/components/ontario-date-input.js.map +1 -1
- package/dist/components/ontario-dropdown-list.js +2 -1
- package/dist/components/ontario-dropdown-list.js.map +1 -1
- package/dist/components/ontario-header.js +2 -4
- package/dist/components/ontario-header.js.map +1 -1
- package/dist/components/ontario-icon-search2.js +6 -0
- package/dist/components/ontario-icon-search2.js.map +1 -0
- package/dist/components/ontario-input.js +2 -1
- package/dist/components/ontario-input.js.map +1 -1
- package/dist/components/ontario-radio-buttons.js +2 -1
- package/dist/components/ontario-radio-buttons.js.map +1 -1
- package/dist/components/ontario-search-box.d.ts +11 -0
- package/dist/components/ontario-search-box.js +269 -0
- package/dist/components/ontario-search-box.js.map +1 -0
- package/dist/components/ontario-step-indicator.js +5 -5
- package/dist/components/ontario-table.js +5 -5
- package/dist/components/ontario-textarea.js +5 -4
- package/dist/components/ontario-textarea.js.map +1 -1
- package/dist/esm/index-603026f7.js +2 -2
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{ontario-accordion_43.entry.js → ontario-accordion_44.entry.js} +339 -78
- package/dist/esm/ontario-accordion_44.entry.js.map +1 -0
- package/dist/esm/ontario-design-system-components.js +1 -1
- package/dist/ontario-design-system-components/ontario-design-system-components.esm.js +1 -1
- package/dist/ontario-design-system-components/ontario-design-system-components.esm.js.map +1 -1
- package/dist/ontario-design-system-components/{p-abe58ec9.entry.js → p-9c3a1be9.entry.js} +1925 -1728
- package/dist/ontario-design-system-components/p-9c3a1be9.entry.js.map +1 -0
- package/dist/types/components/ontario-card/ontario-card-types.d.ts +4 -4
- package/dist/types/components/ontario-card/ontario-card.d.ts +40 -29
- package/dist/types/components/ontario-search-box/ontario-search-box.d.ts +180 -0
- package/dist/types/components.d.ts +199 -16
- package/dist/types/utils/common/input/input.d.ts +2 -1
- package/dist/types/utils/common/input-caption/input-caption.d.ts +7 -1
- package/package.json +2 -2
- package/src/components/ontario-card/ontario-card-types.tsx +33 -4
- package/src/components/ontario-card/ontario-card.scss +54 -40
- package/src/components/ontario-card/ontario-card.tsx +94 -68
- package/src/components/ontario-card/readme.md +57 -27
- package/src/components/ontario-card/test/__snapshots__/ontario-cards.spec.tsx.snap +66 -0
- package/src/components/ontario-card/test/ontario-cards.spec.tsx +27 -13
- package/src/components/ontario-card-collection/readme.md +13 -13
- package/src/components/ontario-checkbox/ontario-checkboxes.scss +0 -1
- package/src/components/ontario-header/service-ontario-header.scss +0 -4
- package/src/components/ontario-hint-text/readme.md +2 -0
- package/src/components/ontario-radio-buttons/ontario-radio-buttons.scss +0 -1
- package/src/components/ontario-search-box/assets/ontario-icon-close.svg +1 -0
- package/src/components/ontario-search-box/assets/ontario-logo--mobile.svg +6 -0
- package/src/components/ontario-search-box/ontario-search-box.scss +141 -0
- package/src/components/ontario-search-box/ontario-search-box.tsx +341 -0
- package/src/components/ontario-search-box/readme.md +132 -0
- package/src/components/ontario-search-box/test/__snapshots__/ontario-search-box.spec.tsx.snap +35 -0
- package/src/components/ontario-search-box/test/ontario-search-box.e2e.ts +21 -0
- package/src/components/ontario-search-box/test/ontario-search-box.spec.tsx +22 -0
- package/src/components.d.ts +199 -16
- package/src/index.html +287 -52
- package/src/utils/common/input/input.tsx +4 -1
- package/src/utils/common/input-caption/input-caption.tsx +9 -3
- package/www/build/ontario-design-system-components.esm.js +1 -1
- package/www/build/ontario-design-system-components.esm.js.map +1 -1
- package/www/build/{p-fdc9ab6d.js → p-84035ac3.js} +1 -1
- package/www/build/{p-abe58ec9.entry.js → p-9c3a1be9.entry.js} +1925 -1728
- package/www/build/p-9c3a1be9.entry.js.map +1 -0
- package/www/index.html +261 -52
- package/dist/cjs/ontario-accordion_43.cjs.entry.js.map +0 -1
- package/dist/esm/ontario-accordion_43.entry.js.map +0 -1
- package/dist/ontario-design-system-components/p-abe58ec9.entry.js.map +0 -1
- 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).
|
|
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
|
-
|
|
23
|
+
layout="horizontal"
|
|
24
24
|
label="Card Title 1"
|
|
25
|
-
image="https://picsum.photos/
|
|
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
|
-
|
|
33
|
+
layout="horizontal"
|
|
34
34
|
label="Card Title 2"
|
|
35
|
-
image="https://picsum.photos/
|
|
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
|
-
|
|
46
|
+
layout="horizontal"
|
|
47
47
|
label="Card Title 1"
|
|
48
|
-
image="https://picsum.photos/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
56
|
+
layout="horizontal"
|
|
57
57
|
label="Card Title 2"
|
|
58
|
-
image="https://picsum.photos/
|
|
59
|
-
|
|
60
|
-
|
|
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");
|
|
@@ -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
|
+
}
|