@politiet/sheriff-web-components 2.7.0 → 2.7.2

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 (96) hide show
  1. package/custom-elements.json +172 -7
  2. package/dist/frameworks/preact.d.ts +4 -1
  3. package/dist/frameworks/preact.d.ts.map +1 -1
  4. package/dist/frameworks/react.d.ts +10 -2
  5. package/dist/frameworks/react.d.ts.map +1 -1
  6. package/dist/frameworks/solidjs.d.ts +1 -0
  7. package/dist/frameworks/solidjs.d.ts.map +1 -1
  8. package/dist/frameworks/svelte.d.ts +1 -0
  9. package/dist/frameworks/svelte.d.ts.map +1 -1
  10. package/dist/frameworks/vue.d.ts +1 -0
  11. package/dist/frameworks/vue.d.ts.map +1 -1
  12. package/dist/index.d.ts +2 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/mixins/sds-dialog-target-mixin.d.ts +2 -0
  17. package/dist/mixins/sds-dialog-target-mixin.d.ts.map +1 -1
  18. package/dist/mixins/sds-dialog-target-mixin.js +31 -15
  19. package/dist/mixins/sds-dialog-target-mixin.js.map +1 -1
  20. package/dist/mixins/sds-popover-target-mixin.d.ts +1 -1
  21. package/dist/mixins/sds-popover-target-mixin.d.ts.map +1 -1
  22. package/dist/mixins/sds-popover-target-mixin.js.map +1 -1
  23. package/dist/react-wrappers/SDSPopoverWrapper.d.ts +4 -1
  24. package/dist/react-wrappers/SDSPopoverWrapper.d.ts.map +1 -1
  25. package/dist/react-wrappers/SDSPopoverWrapper.js +3 -1
  26. package/dist/react-wrappers/SDSPopoverWrapper.js.map +1 -1
  27. package/dist/react-wrappers/SDSTooltipWrapper.d.ts +6 -0
  28. package/dist/react-wrappers/SDSTooltipWrapper.d.ts.map +1 -0
  29. package/dist/react-wrappers/SDSTooltipWrapper.js +12 -0
  30. package/dist/react-wrappers/SDSTooltipWrapper.js.map +1 -0
  31. package/dist/react-wrappers/index.d.ts +1 -0
  32. package/dist/react-wrappers/index.d.ts.map +1 -1
  33. package/dist/react-wrappers/index.js +1 -0
  34. package/dist/react-wrappers/index.js.map +1 -1
  35. package/dist/sds-button/sds-button.component.d.ts +1 -1
  36. package/dist/sds-button/sds-button.component.d.ts.map +1 -1
  37. package/dist/sds-button/sds-button.component.js +1 -1
  38. package/dist/sds-button/sds-button.component.js.map +1 -1
  39. package/dist/sds-dialog/sds-dialog.component.js +1 -1
  40. package/dist/sds-dialog/sds-dialog.component.js.map +1 -1
  41. package/dist/sds-popover/assets/popover-styles.d.ts.map +1 -1
  42. package/dist/sds-popover/assets/popover-styles.js +1 -1
  43. package/dist/sds-popover/assets/popover-styles.js.map +1 -1
  44. package/dist/sds-popover/sds-popover.d.ts +3 -1
  45. package/dist/sds-popover/sds-popover.d.ts.map +1 -1
  46. package/dist/sds-popover/sds-popover.js +18 -4
  47. package/dist/sds-popover/sds-popover.js.map +1 -1
  48. package/dist/sds-tooltip/assets/tooltip-styles.d.ts +3 -0
  49. package/dist/sds-tooltip/assets/tooltip-styles.d.ts.map +1 -0
  50. package/dist/sds-tooltip/assets/tooltip-styles.js +3 -0
  51. package/dist/sds-tooltip/assets/tooltip-styles.js.map +1 -0
  52. package/dist/sds-tooltip/sds-tooltip.d.ts +35 -0
  53. package/dist/sds-tooltip/sds-tooltip.d.ts.map +1 -0
  54. package/dist/sds-tooltip/sds-tooltip.js +140 -0
  55. package/dist/sds-tooltip/sds-tooltip.js.map +1 -0
  56. package/dist/sds-tooltip/sds-tooltip.styles.d.ts +2 -0
  57. package/dist/sds-tooltip/sds-tooltip.styles.d.ts.map +1 -0
  58. package/dist/sds-tooltip/sds-tooltip.styles.js +87 -0
  59. package/dist/sds-tooltip/sds-tooltip.styles.js.map +1 -0
  60. package/dist/shared/assets/positioning.js +1 -0
  61. package/dist/shared/positioning.d.ts +2 -0
  62. package/dist/shared/positioning.d.ts.map +1 -0
  63. package/dist/shared/positioning.js +2 -0
  64. package/dist/shared/positioning.js.map +1 -0
  65. package/dist/sheriff-web-components.js +284 -201
  66. package/package.json +10 -4
  67. package/web-types.json +260 -11
  68. package/dist/playwright-util/custom-matchers.d.ts +0 -7
  69. package/dist/playwright-util/custom-matchers.d.ts.map +0 -1
  70. package/dist/playwright-util/custom-matchers.js +0 -21
  71. package/dist/playwright-util/custom-matchers.js.map +0 -1
  72. package/dist/playwright-util/form.d.ts +0 -3
  73. package/dist/playwright-util/form.d.ts.map +0 -1
  74. package/dist/playwright-util/form.js +0 -44
  75. package/dist/playwright-util/form.js.map +0 -1
  76. package/dist/sds-button/sds-button.spec.d.ts +0 -2
  77. package/dist/sds-button/sds-button.spec.d.ts.map +0 -1
  78. package/dist/sds-button/sds-button.spec.js +0 -182
  79. package/dist/sds-button/sds-button.spec.js.map +0 -1
  80. package/dist/sds-checkbox/sds-checkbox.spec.d.ts +0 -2
  81. package/dist/sds-checkbox/sds-checkbox.spec.d.ts.map +0 -1
  82. package/dist/sds-checkbox/sds-checkbox.spec.js +0 -74
  83. package/dist/sds-checkbox/sds-checkbox.spec.js.map +0 -1
  84. package/dist/sds-dialog/sds-dialog.spec.d.ts +0 -2
  85. package/dist/sds-dialog/sds-dialog.spec.d.ts.map +0 -1
  86. package/dist/sds-dialog/sds-dialog.spec.js +0 -50
  87. package/dist/sds-dialog/sds-dialog.spec.js.map +0 -1
  88. package/dist/sds-popover/assets/positioning.js +0 -1
  89. package/dist/sds-radio/sds-radio.spec.d.ts +0 -2
  90. package/dist/sds-radio/sds-radio.spec.d.ts.map +0 -1
  91. package/dist/sds-radio/sds-radio.spec.js +0 -71
  92. package/dist/sds-radio/sds-radio.spec.js.map +0 -1
  93. package/dist/sds-textfield/sds-textfield.spec.d.ts +0 -2
  94. package/dist/sds-textfield/sds-textfield.spec.d.ts.map +0 -1
  95. package/dist/sds-textfield/sds-textfield.spec.js +0 -137
  96. package/dist/sds-textfield/sds-textfield.spec.js.map +0 -1
@@ -1,137 +0,0 @@
1
- import { test, expect } from '@playwright/test';
2
- import { expect as sdsExpect } from '../playwright-util/custom-matchers';
3
- const textfieldIds = [
4
- 'textfield-name',
5
- 'textfield-label',
6
- 'textfield-placeholder',
7
- 'textfield-helptext',
8
- 'textfield-disabled',
9
- 'textfield-readonly',
10
- 'textfield-required',
11
- 'textfield-error',
12
- 'textfield-icon',
13
- 'textfield-autocomplete-off',
14
- 'textfield-autocomplete-on',
15
- 'textfield-pattern',
16
- 'textfield-min',
17
- 'textfield-max',
18
- ];
19
- const pageUrl = 'iframe.html?viewMode=docs&id=test-textfield--docs';
20
- test.describe('textfield-component', () => {
21
- test.beforeEach(async ({ page }) => {
22
- await page.goto(pageUrl);
23
- });
24
- test('visibility', async ({ page }) => {
25
- for (const id of textfieldIds) {
26
- await expect(page.locator(`#${id}`)).toBeVisible();
27
- }
28
- });
29
- test('design-implementation', async ({ page }) => {
30
- await page.reload();
31
- for (const id of textfieldIds) {
32
- // Default state
33
- await expect(page.locator(`#${id}`)).toHaveScreenshot(`${id}.png`);
34
- // Hover state
35
- if (!id.includes('disabled')) {
36
- await page.locator(`#${id}`).hover();
37
- await expect(page.locator(`#${id}`)).toHaveScreenshot(`${id}-hover.png`);
38
- }
39
- // Focus state
40
- await page.evaluate((id) => {
41
- const element = document.getElementById(id);
42
- if (element) {
43
- const parentDiv = document.createElement('div');
44
- parentDiv.style.padding = '10px';
45
- parentDiv.style.backgroundColor = 'white';
46
- element.parentNode?.insertBefore(parentDiv, element);
47
- parentDiv.appendChild(element);
48
- }
49
- }, id);
50
- await page.locator(`#${id}`).focus();
51
- const parentDiv = await page.locator(`#${id}`).locator('xpath=..');
52
- await expect(parentDiv).toHaveScreenshot(`${id}-focus.png`);
53
- }
54
- });
55
- test('form-submission', async ({ page }) => {
56
- let requestUrl;
57
- page.on('request', (request) => {
58
- if (request.url().includes('iframe.html?name=John')) {
59
- requestUrl = new URL(request.url());
60
- }
61
- });
62
- await page.locator('#textfield-name').pressSequentially('John');
63
- await page.locator('#submit-button').click();
64
- await expect(requestUrl?.searchParams.get('name')).toBe('John');
65
- });
66
- test('form-reset', async ({ page }) => {
67
- await page.locator('#textfield-name').pressSequentially('John');
68
- await page.locator('#reset-button').click();
69
- const value = await page.locator('#textfield-name').getAttribute('value');
70
- expect(value).toBeNull();
71
- });
72
- test('minlength', async ({ page }) => {
73
- const textfield = page.locator('#textfield-min');
74
- await expect(textfield).toHaveAttribute('minlength', '4');
75
- const nestedInputHasMinlength = await textfield.evaluate((el) => el.hasAttribute('minlength'));
76
- expect(nestedInputHasMinlength).toBe(true);
77
- });
78
- test('maxlength', async ({ page }) => {
79
- const textfield = page.locator('#textfield-max');
80
- await textfield.pressSequentially('abcdef');
81
- await sdsExpect(textfield).toHaveValue('abcd');
82
- });
83
- test('pattern', async ({ page }) => {
84
- const textfield = page.locator('#textfield-pattern');
85
- // Non-digits → invalid
86
- await textfield.pressSequentially('abcd');
87
- let isValid = await textfield.evaluate((el) => el.checkValidity());
88
- expect(isValid).toBe(false);
89
- // Too few digits → invalid
90
- await page.goto(pageUrl);
91
- await textfield.pressSequentially('123');
92
- isValid = await textfield.evaluate((el) => el.checkValidity());
93
- expect(isValid).toBe(false);
94
- // Exactly 4 digits → valid
95
- await page.goto(pageUrl);
96
- await textfield.pressSequentially('1234');
97
- isValid = await textfield.evaluate((el) => el.checkValidity());
98
- expect(isValid).toBe(true);
99
- // Too many digits → invalid
100
- await page.goto(pageUrl);
101
- await textfield.pressSequentially('12345');
102
- isValid = await textfield.evaluate((el) => el.checkValidity());
103
- expect(isValid).toBe(false);
104
- });
105
- test('required', async ({ page }) => {
106
- const textfield = page.locator('#textfield-required');
107
- // No value → invalid
108
- let isValid = await textfield.evaluate((el) => el.checkValidity());
109
- expect(isValid).toBe(false);
110
- // Has value → valid
111
- await page.goto(pageUrl);
112
- await textfield.pressSequentially('abc');
113
- isValid = await textfield.evaluate((el) => el.checkValidity());
114
- expect(isValid).toBe(true);
115
- });
116
- test('readonly', async ({ page }) => {
117
- const textfield = page.locator('#textfield-readonly');
118
- await textfield.pressSequentially('abc');
119
- await sdsExpect(textfield).toHaveValue('Kan ikke endres');
120
- });
121
- test('autocomplete on/off', async ({ page }) => {
122
- const textfields = [
123
- { id: 'textfield-autocomplete-off', expected: 'off' },
124
- { id: 'textfield-autocomplete-on', expected: 'on' },
125
- ];
126
- for (const { id, expected } of textfields) {
127
- const host = page.locator(`#${id}`);
128
- await expect(host).toHaveAttribute('autocomplete', expected);
129
- const shadowDomInput = await host.evaluate((el) => {
130
- const input = el.shadowRoot?.querySelector('input');
131
- return input?.autocomplete ?? null;
132
- });
133
- expect(shadowDomInput).toBe(expected);
134
- }
135
- });
136
- });
137
- //# sourceMappingURL=sds-textfield.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sds-textfield.spec.js","sourceRoot":"","sources":["../../src/sds-textfield/sds-textfield.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from '@playwright/test';\nimport { expect as sdsExpect } from '../playwright-util/custom-matchers';\n\nconst textfieldIds = [\n\t'textfield-name',\n\t'textfield-label',\n\t'textfield-placeholder',\n\t'textfield-helptext',\n\t'textfield-disabled',\n\t'textfield-readonly',\n\t'textfield-required',\n\t'textfield-error',\n\t'textfield-icon',\n\t'textfield-autocomplete-off',\n\t'textfield-autocomplete-on',\n\t'textfield-pattern',\n\t'textfield-min',\n\t'textfield-max',\n];\n\nconst pageUrl = 'iframe.html?viewMode=docs&id=test-textfield--docs';\n\ntest.describe('textfield-component', () => {\n\ttest.beforeEach(async ({ page }) => {\n\t\tawait page.goto(pageUrl);\n\t});\n\n\ttest('visibility', async ({ page }) => {\n\t\tfor (const id of textfieldIds) {\n\t\t\tawait expect(page.locator(`#${id}`)).toBeVisible();\n\t\t}\n\t});\n\n\ttest('design-implementation', async ({ page }) => {\n\t\tawait page.reload();\n\n\t\tfor (const id of textfieldIds) {\n\t\t\t// Default state\n\t\t\tawait expect(page.locator(`#${id}`)).toHaveScreenshot(`${id}.png`);\n\t\t\t// Hover state\n\t\t\tif (!id.includes('disabled')) {\n\t\t\t\tawait page.locator(`#${id}`).hover();\n\t\t\t\tawait expect(page.locator(`#${id}`)).toHaveScreenshot(`${id}-hover.png`);\n\t\t\t}\n\t\t\t// Focus state\n\t\t\tawait page.evaluate((id) => {\n\t\t\t\tconst element = document.getElementById(id);\n\t\t\t\tif (element) {\n\t\t\t\t\tconst parentDiv = document.createElement('div');\n\t\t\t\t\tparentDiv.style.padding = '10px';\n\t\t\t\t\tparentDiv.style.backgroundColor = 'white';\n\t\t\t\t\telement.parentNode?.insertBefore(parentDiv, element);\n\t\t\t\t\tparentDiv.appendChild(element);\n\t\t\t\t}\n\t\t\t}, id);\n\t\t\tawait page.locator(`#${id}`).focus();\n\t\t\tconst parentDiv = await page.locator(`#${id}`).locator('xpath=..');\n\t\t\tawait expect(parentDiv).toHaveScreenshot(`${id}-focus.png`);\n\t\t}\n\t});\n\n\ttest('form-submission', async ({ page }) => {\n\t\tlet requestUrl: URL | undefined;\n\t\tpage.on('request', (request) => {\n\t\t\tif (request.url().includes('iframe.html?name=John')) {\n\t\t\t\trequestUrl = new URL(request.url());\n\t\t\t}\n\t\t});\n\n\t\tawait page.locator('#textfield-name').pressSequentially('John');\n\t\tawait page.locator('#submit-button').click();\n\t\tawait expect(requestUrl?.searchParams.get('name')).toBe('John');\n\t});\n\n\ttest('form-reset', async ({ page }) => {\n\t\tawait page.locator('#textfield-name').pressSequentially('John');\n\t\tawait page.locator('#reset-button').click();\n\t\tconst value = await page.locator('#textfield-name').getAttribute('value');\n\t\texpect(value).toBeNull();\n\t});\n\n\ttest('minlength', async ({ page }) => {\n\t\tconst textfield = page.locator('#textfield-min');\n\t\tawait expect(textfield).toHaveAttribute('minlength', '4');\n\t\tconst nestedInputHasMinlength = await textfield.evaluate((el: HTMLInputElement) => el.hasAttribute('minlength'));\n\t\texpect(nestedInputHasMinlength).toBe(true);\n\t});\n\n\ttest('maxlength', async ({ page }) => {\n\t\tconst textfield = page.locator('#textfield-max');\n\n\t\tawait textfield.pressSequentially('abcdef');\n\t\tawait sdsExpect(textfield).toHaveValue('abcd');\n\t});\n\n\ttest('pattern', async ({ page }) => {\n\t\tconst textfield = page.locator('#textfield-pattern');\n\n\t\t// Non-digits → invalid\n\t\tawait textfield.pressSequentially('abcd');\n\t\tlet isValid = await textfield.evaluate((el: HTMLInputElement) => el.checkValidity());\n\t\texpect(isValid).toBe(false);\n\n\t\t// Too few digits → invalid\n\t\tawait page.goto(pageUrl);\n\t\tawait textfield.pressSequentially('123');\n\t\tisValid = await textfield.evaluate((el: HTMLInputElement) => el.checkValidity());\n\t\texpect(isValid).toBe(false);\n\n\t\t// Exactly 4 digits → valid\n\t\tawait page.goto(pageUrl);\n\t\tawait textfield.pressSequentially('1234');\n\t\tisValid = await textfield.evaluate((el: HTMLInputElement) => el.checkValidity());\n\t\texpect(isValid).toBe(true);\n\n\t\t// Too many digits → invalid\n\t\tawait page.goto(pageUrl);\n\t\tawait textfield.pressSequentially('12345');\n\t\tisValid = await textfield.evaluate((el: HTMLInputElement) => el.checkValidity());\n\t\texpect(isValid).toBe(false);\n\t});\n\n\ttest('required', async ({ page }) => {\n\t\tconst textfield = page.locator('#textfield-required');\n\n\t\t// No value → invalid\n\t\tlet isValid = await textfield.evaluate((el: HTMLInputElement) => el.checkValidity());\n\t\texpect(isValid).toBe(false);\n\n\t\t// Has value → valid\n\t\tawait page.goto(pageUrl);\n\t\tawait textfield.pressSequentially('abc');\n\t\tisValid = await textfield.evaluate((el: HTMLInputElement) => el.checkValidity());\n\t\texpect(isValid).toBe(true);\n\t});\n\n\ttest('readonly', async ({ page }) => {\n\t\tconst textfield = page.locator('#textfield-readonly');\n\t\tawait textfield.pressSequentially('abc');\n\t\tawait sdsExpect(textfield).toHaveValue('Kan ikke endres');\n\t});\n\n\ttest('autocomplete on/off', async ({ page }) => {\n\t\tconst textfields = [\n\t\t\t{ id: 'textfield-autocomplete-off', expected: 'off' },\n\t\t\t{ id: 'textfield-autocomplete-on', expected: 'on' },\n\t\t];\n\n\t\tfor (const { id, expected } of textfields) {\n\t\t\tconst host = page.locator(`#${id}`);\n\n\t\t\tawait expect(host).toHaveAttribute('autocomplete', expected);\n\t\t\tconst shadowDomInput = await host.evaluate((el: HTMLElement) => {\n\t\t\t\tconst input = el.shadowRoot?.querySelector('input') as HTMLInputElement | null;\n\t\t\t\treturn input?.autocomplete ?? null;\n\t\t\t});\n\t\t\texpect(shadowDomInput).toBe(expected);\n\t\t}\n\t});\n});\n"]}