@ks-digital/designsystem-angular 0.0.1-alpha.25 → 0.0.1-alpha.27
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/fesm2022/ks-digital-designsystem-angular.mjs +1100 -0
- package/fesm2022/ks-digital-designsystem-angular.mjs.map +1 -0
- package/index.d.ts +333 -0
- package/package.json +15 -20
- package/.storybook/customTheme.ts +0 -15
- package/.storybook/default-args.ts +0 -18
- package/.storybook/main.ts +0 -27
- package/.storybook/manager.ts +0 -10
- package/.storybook/preview-head.html +0 -16
- package/.storybook/preview.ts +0 -70
- package/.storybook/themes.ts +0 -9
- package/.storybook/tsconfig.json +0 -16
- package/.storybook/vite.config.mts +0 -5
- package/eslint.config.mjs +0 -28
- package/ng-package.json +0 -9
- package/project.json +0 -81
- package/src/components/alert/alert.mdx +0 -46
- package/src/components/alert/alert.spec.ts +0 -33
- package/src/components/alert/alert.stories.ts +0 -138
- package/src/components/alert/alert.ts +0 -46
- package/src/components/alert/index.ts +0 -1
- package/src/components/button/button.mdx +0 -40
- package/src/components/button/button.spec.ts +0 -86
- package/src/components/button/button.stories.ts +0 -123
- package/src/components/button/button.ts +0 -60
- package/src/components/button/index.ts +0 -1
- package/src/components/card/card-block.ts +0 -10
- package/src/components/card/card.mdx +0 -100
- package/src/components/card/card.spec.ts +0 -70
- package/src/components/card/card.stories.ts +0 -101
- package/src/components/card/card.ts +0 -44
- package/src/components/card/index.ts +0 -2
- package/src/components/checkbox/README.md +0 -13
- package/src/components/checkbox/checkbox.mdx +0 -50
- package/src/components/checkbox/checkbox.spec.ts +0 -21
- package/src/components/checkbox/checkbox.stories.ts +0 -182
- package/src/components/checkbox/index.ts +0 -0
- package/src/components/colors.ts +0 -36
- package/src/components/common-inputs.ts +0 -30
- package/src/components/details/controlled-details.ts +0 -63
- package/src/components/details/details-content.ts +0 -7
- package/src/components/details/details-summary.ts +0 -7
- package/src/components/details/details.mdx +0 -89
- package/src/components/details/details.spec.ts +0 -56
- package/src/components/details/details.stories.ts +0 -129
- package/src/components/details/details.ts +0 -69
- package/src/components/details/index.ts +0 -3
- package/src/components/field/field-counter.ts +0 -56
- package/src/components/field/field-description.ts +0 -10
- package/src/components/field/field-error.ts +0 -13
- package/src/components/field/field-observer.ts +0 -121
- package/src/components/field/field-state.ts +0 -21
- package/src/components/field/field.mdx +0 -40
- package/src/components/field/field.spec.ts +0 -131
- package/src/components/field/field.stories.ts +0 -98
- package/src/components/field/field.ts +0 -70
- package/src/components/field/index.ts +0 -3
- package/src/components/fieldset/fieldset-description.ts +0 -8
- package/src/components/fieldset/fieldset-legend.ts +0 -11
- package/src/components/fieldset/fieldset.spec.ts +0 -80
- package/src/components/fieldset/fieldset.ts +0 -11
- package/src/components/fieldset/index.ts +0 -3
- package/src/components/input/index.ts +0 -1
- package/src/components/input/input.mdx +0 -11
- package/src/components/input/input.spec.ts +0 -25
- package/src/components/input/input.stories.ts +0 -72
- package/src/components/input/input.ts +0 -67
- package/src/components/label/index.ts +0 -1
- package/src/components/label/label.ts +0 -17
- package/src/components/paragraph/index.ts +0 -1
- package/src/components/paragraph/paragraph.ts +0 -10
- package/src/components/popover/controlled-popover.ts +0 -62
- package/src/components/popover/index.ts +0 -1
- package/src/components/popover/popover.mdx +0 -81
- package/src/components/popover/popover.spec.ts +0 -143
- package/src/components/popover/popover.stories.ts +0 -63
- package/src/components/popover/popover.ts +0 -186
- package/src/components/radio/radio.mdx +0 -117
- package/src/components/radio/radio.stories.ts +0 -226
- package/src/components/search/index.ts +0 -4
- package/src/components/search/search-button.ts +0 -35
- package/src/components/search/search-clear.ts +0 -57
- package/src/components/search/search-input.ts +0 -18
- package/src/components/search/search.mdx +0 -56
- package/src/components/search/search.spec.ts +0 -48
- package/src/components/search/search.stories.ts +0 -205
- package/src/components/search/search.ts +0 -50
- package/src/components/spinner/index.ts +0 -1
- package/src/components/spinner/spinner.mdx +0 -24
- package/src/components/spinner/spinner.spec.ts +0 -13
- package/src/components/spinner/spinner.stories.ts +0 -54
- package/src/components/spinner/spinner.ts +0 -62
- package/src/components/switch/switch.mdx +0 -82
- package/src/components/switch/switch.stories.ts +0 -94
- package/src/components/textarea/textarea.mdx +0 -14
- package/src/components/textarea/textarea.stories.ts +0 -52
- package/src/components/validation-message/index.ts +0 -1
- package/src/components/validation-message/validation-message.ts +0 -11
- package/src/index.ts +0 -14
- package/src/test-setup.ts +0 -12
- package/src/utils/log-if-devmode.ts +0 -13
- package/src/utils/random-id.ts +0 -3
- package/tsconfig.json +0 -34
- package/tsconfig.lib.json +0 -28
- package/tsconfig.lib.prod.json +0 -9
- package/tsconfig.spec.json +0 -30
- package/vite.config.mts +0 -35
|
@@ -0,0 +1,1100 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, Directive, Component, booleanAttribute, inject, ElementRef, output, viewChild, CUSTOM_ELEMENTS_SCHEMA, signal, computed, Injectable, numberAttribute, effect, contentChild, contentChildren, afterNextRender, isDevMode } from '@angular/core';
|
|
3
|
+
import '@u-elements/u-details';
|
|
4
|
+
import { autoUpdate, computePosition, offset, flip, shift } from '@floating-ui/dom';
|
|
5
|
+
|
|
6
|
+
/* eslint-disable @angular-eslint/no-input-rename */
|
|
7
|
+
/**
|
|
8
|
+
* We use input aliasing to bridge the gap between Angular's camelCase property naming convention and our HTML data attributes.
|
|
9
|
+
* This approach allows us to use valid HTML data attributes as documented by Designsystemet while maintaining
|
|
10
|
+
* proper TypeScript intellisense support.
|
|
11
|
+
*
|
|
12
|
+
* Todo: Some components are using only a subset of colors, e.g., SeverityColors for Alert. We should reconsider this directive
|
|
13
|
+
*/
|
|
14
|
+
class CommonInputs {
|
|
15
|
+
/**
|
|
16
|
+
* Changes size for descendant Designsystemet components. Select from predefined sizes.
|
|
17
|
+
* @attribute data-size
|
|
18
|
+
*/
|
|
19
|
+
dataSize = input(undefined, ...(ngDevMode ? [{ debugName: "dataSize", alias: 'data-size' }] : [{ alias: 'data-size' }]));
|
|
20
|
+
/**
|
|
21
|
+
* Changes color for descendant Designsystemet components.
|
|
22
|
+
* Select from predefined colors and colors defined using theme.designsystemet.no.
|
|
23
|
+
* @attribute data-color
|
|
24
|
+
*/
|
|
25
|
+
dataColor = input(undefined, ...(ngDevMode ? [{ debugName: "dataColor", alias: 'data-color' }] : [{ alias: 'data-color' }]));
|
|
26
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CommonInputs, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
27
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.9", type: CommonInputs, isStandalone: true, inputs: { dataSize: { classPropertyName: "dataSize", publicName: "data-size", isSignal: true, isRequired: false, transformFunction: null }, dataColor: { classPropertyName: "dataColor", publicName: "data-color", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
28
|
+
}
|
|
29
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CommonInputs, decorators: [{
|
|
30
|
+
type: Directive
|
|
31
|
+
}], propDecorators: { dataSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "data-size", required: false }] }], dataColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "data-color", required: false }] }] } });
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Alerts are used to inform users about important information, warnings, errors, or success.
|
|
35
|
+
*/
|
|
36
|
+
class Alert {
|
|
37
|
+
/**
|
|
38
|
+
* The color variant of the alert.
|
|
39
|
+
*/
|
|
40
|
+
/* eslint-disable-next-line @angular-eslint/no-input-rename */
|
|
41
|
+
dataColor = input(undefined, ...(ngDevMode ? [{ debugName: "dataColor", alias: 'data-color' }] : [{ alias: 'data-color' }]));
|
|
42
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Alert, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
43
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: Alert, isStandalone: true, selector: "ksd-alert", inputs: { dataColor: { classPropertyName: "dataColor", publicName: "data-color", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "ds-alert" }, hostDirectives: [{ directive: CommonInputs, inputs: ["data-size", "data-size"] }], ngImport: i0, template: ` <ng-content />`, isInline: true, styles: [":host{--dsc-alert-icon-url: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M128,24A104,104,0,1,0,232,128A104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z'/%3E%3C/svg%3E\")}:host[data-color=warning]{--dsc-alert-icon-url: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M120,136V80a8,8,0,0,1,16,0v56a8,8,0,0,1-16,0ZM232,91.55v72.9a15.86,15.86,0,0,1-4.69,11.31l-51.55,51.55A15.86,15.86,0,0,1,164.45,232H91.55a15.86,15.86,0,0,1-11.31-4.69L28.69,175.76A15.86,15.86,0,0,1,24,164.45V91.55a15.86,15.86,0,0,1,4.69-11.31L80.24,28.69A15.86,15.86,0,0,1,91.55,24h72.9a15.86,15.86,0,0,1,11.31,4.69l51.55,51.55A15.86,15.86,0,0,1,232,91.55Zm-16,0L164.45,40H91.55L40,91.55v72.9L91.55,216h72.9L216,164.45ZM128,160a12,12,0,1,0,12,12A12,12,0,0,0,128,160Z'/%3E%3C/svg%3E\")}:host[data-color=success]{--dsc-alert-icon-url: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M173.66,98.34a8,8,0,0,1,0,11.32l-56,56a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L112,148.69l50.34-50.35A8,8,0,0,1,173.66,98.34ZM232,128A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z'%3E%3C/path%3E%3C/svg%3E\")}:host[data-color=danger]{--dsc-alert-icon-url: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M165.66,101.66,139.31,128l26.35,26.34a8,8,0,0,1-11.32,11.32L128,139.31l-26.34,26.35a8,8,0,0,1-11.32-11.32L116.69,128,90.34,101.66a8,8,0,0,1,11.32-11.32L128,116.69l26.34-26.35a8,8,0,0,1,11.32,11.32ZM232,128A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z'%3E%3C/path%3E%3C/svg%3E\")}\n"] });
|
|
44
|
+
}
|
|
45
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Alert, decorators: [{
|
|
46
|
+
type: Component,
|
|
47
|
+
args: [{ selector: 'ksd-alert', template: ` <ng-content />`, host: {
|
|
48
|
+
class: 'ds-alert',
|
|
49
|
+
}, hostDirectives: [
|
|
50
|
+
{
|
|
51
|
+
directive: CommonInputs,
|
|
52
|
+
inputs: ['data-size'],
|
|
53
|
+
},
|
|
54
|
+
], styles: [":host{--dsc-alert-icon-url: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M128,24A104,104,0,1,0,232,128A104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z'/%3E%3C/svg%3E\")}:host[data-color=warning]{--dsc-alert-icon-url: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M120,136V80a8,8,0,0,1,16,0v56a8,8,0,0,1-16,0ZM232,91.55v72.9a15.86,15.86,0,0,1-4.69,11.31l-51.55,51.55A15.86,15.86,0,0,1,164.45,232H91.55a15.86,15.86,0,0,1-11.31-4.69L28.69,175.76A15.86,15.86,0,0,1,24,164.45V91.55a15.86,15.86,0,0,1,4.69-11.31L80.24,28.69A15.86,15.86,0,0,1,91.55,24h72.9a15.86,15.86,0,0,1,11.31,4.69l51.55,51.55A15.86,15.86,0,0,1,232,91.55Zm-16,0L164.45,40H91.55L40,91.55v72.9L91.55,216h72.9L216,164.45ZM128,160a12,12,0,1,0,12,12A12,12,0,0,0,128,160Z'/%3E%3C/svg%3E\")}:host[data-color=success]{--dsc-alert-icon-url: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M173.66,98.34a8,8,0,0,1,0,11.32l-56,56a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L112,148.69l50.34-50.35A8,8,0,0,1,173.66,98.34ZM232,128A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z'%3E%3C/path%3E%3C/svg%3E\")}:host[data-color=danger]{--dsc-alert-icon-url: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M165.66,101.66,139.31,128l26.35,26.34a8,8,0,0,1-11.32,11.32L128,139.31l-26.34,26.35a8,8,0,0,1-11.32-11.32L116.69,128,90.34,101.66a8,8,0,0,1,11.32-11.32L128,116.69l26.34-26.35a8,8,0,0,1,11.32,11.32ZM232,128A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z'%3E%3C/path%3E%3C/svg%3E\")}\n"] }]
|
|
55
|
+
}], propDecorators: { dataColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "data-color", required: false }] }] } });
|
|
56
|
+
|
|
57
|
+
/* eslint-disable @angular-eslint/no-input-rename */
|
|
58
|
+
class Spinner {
|
|
59
|
+
/**
|
|
60
|
+
* Aria-label for the spinner
|
|
61
|
+
*/
|
|
62
|
+
ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel", alias: 'aria-label' }] : [{ alias: 'aria-label' }]));
|
|
63
|
+
/**
|
|
64
|
+
* Aria-label for the spinner
|
|
65
|
+
*/
|
|
66
|
+
dataSize = input(undefined, ...(ngDevMode ? [{ debugName: "dataSize", alias: 'data-size' }] : [{ alias: 'data-size' }]));
|
|
67
|
+
/**
|
|
68
|
+
* Aria-label for the spinner
|
|
69
|
+
*/
|
|
70
|
+
dataColor = input(undefined, ...(ngDevMode ? [{ debugName: "dataColor", alias: 'data-color' }] : [{ alias: 'data-color' }]));
|
|
71
|
+
/**
|
|
72
|
+
* Aria-hidden for the spinner
|
|
73
|
+
*/
|
|
74
|
+
ariaHidden = input(undefined, ...(ngDevMode ? [{ debugName: "ariaHidden", transform: booleanAttribute,
|
|
75
|
+
alias: 'aria-hidden' }] : [{
|
|
76
|
+
transform: booleanAttribute,
|
|
77
|
+
alias: 'aria-hidden',
|
|
78
|
+
}]));
|
|
79
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Spinner, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
80
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: Spinner, isStandalone: true, selector: "ksd-spinner", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, dataSize: { classPropertyName: "dataSize", publicName: "data-size", isSignal: true, isRequired: false, transformFunction: null }, dataColor: { classPropertyName: "dataColor", publicName: "data-color", isSignal: true, isRequired: false, transformFunction: null }, ariaHidden: { classPropertyName: "ariaHidden", publicName: "aria-hidden", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
81
|
+
<svg
|
|
82
|
+
class="ds-spinner"
|
|
83
|
+
role="img"
|
|
84
|
+
viewBox="0 0 50 50"
|
|
85
|
+
[attr.data-size]="dataSize()"
|
|
86
|
+
[attr.data-color]="dataColor()"
|
|
87
|
+
>
|
|
88
|
+
<circle
|
|
89
|
+
class="ds-spinner__background"
|
|
90
|
+
cx="25"
|
|
91
|
+
cy="25"
|
|
92
|
+
r="20"
|
|
93
|
+
fill="none"
|
|
94
|
+
stroke-width="5"
|
|
95
|
+
/>
|
|
96
|
+
<circle
|
|
97
|
+
class="ds-spinner__circle"
|
|
98
|
+
cx="25"
|
|
99
|
+
cy="25"
|
|
100
|
+
r="20"
|
|
101
|
+
fill="none"
|
|
102
|
+
stroke-width="5"
|
|
103
|
+
/>
|
|
104
|
+
</svg>
|
|
105
|
+
`, isInline: true, styles: [":host{display:contents}\n"] });
|
|
106
|
+
}
|
|
107
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Spinner, decorators: [{
|
|
108
|
+
type: Component,
|
|
109
|
+
args: [{ selector: 'ksd-spinner', template: `
|
|
110
|
+
<svg
|
|
111
|
+
class="ds-spinner"
|
|
112
|
+
role="img"
|
|
113
|
+
viewBox="0 0 50 50"
|
|
114
|
+
[attr.data-size]="dataSize()"
|
|
115
|
+
[attr.data-color]="dataColor()"
|
|
116
|
+
>
|
|
117
|
+
<circle
|
|
118
|
+
class="ds-spinner__background"
|
|
119
|
+
cx="25"
|
|
120
|
+
cy="25"
|
|
121
|
+
r="20"
|
|
122
|
+
fill="none"
|
|
123
|
+
stroke-width="5"
|
|
124
|
+
/>
|
|
125
|
+
<circle
|
|
126
|
+
class="ds-spinner__circle"
|
|
127
|
+
cx="25"
|
|
128
|
+
cy="25"
|
|
129
|
+
r="20"
|
|
130
|
+
fill="none"
|
|
131
|
+
stroke-width="5"
|
|
132
|
+
/>
|
|
133
|
+
</svg>
|
|
134
|
+
`, styles: [":host{display:contents}\n"] }]
|
|
135
|
+
}], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], dataSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "data-size", required: false }] }], dataColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "data-color", required: false }] }], ariaHidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-hidden", required: false }] }] } });
|
|
136
|
+
|
|
137
|
+
class Button {
|
|
138
|
+
/**
|
|
139
|
+
* Specify which variant to use
|
|
140
|
+
* @default 'primary'
|
|
141
|
+
*/
|
|
142
|
+
variant = input('primary', ...(ngDevMode ? [{ debugName: "variant" }] : []));
|
|
143
|
+
/**
|
|
144
|
+
* Toggle loading state.
|
|
145
|
+
* Pass an element if you want to display a custom loader.
|
|
146
|
+
*
|
|
147
|
+
* @default false
|
|
148
|
+
*/
|
|
149
|
+
loading = input(false, ...(ngDevMode ? [{ debugName: "loading", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
150
|
+
/**
|
|
151
|
+
* Disables element
|
|
152
|
+
*/
|
|
153
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
154
|
+
/**
|
|
155
|
+
* If this is a button with only an icon
|
|
156
|
+
*/
|
|
157
|
+
icon = input(false, ...(ngDevMode ? [{ debugName: "icon", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
158
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Button, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
159
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: Button, isStandalone: true, selector: "button[ksd-button], a[ksd-button]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "button" }, properties: { "attr.data-variant": "variant()", "attr.data-icon": "icon() || null", "attr.disabled": "disabled() ? true : null", "attr.aria-busy": "loading() ? true : null" }, classAttribute: "ds-button" }, hostDirectives: [{ directive: CommonInputs, inputs: ["data-size", "data-size", "data-color", "data-color"] }], ngImport: i0, template: `
|
|
160
|
+
@if (loading()) {
|
|
161
|
+
<ksd-spinner aria-hidden="true" />
|
|
162
|
+
}
|
|
163
|
+
<ng-content />
|
|
164
|
+
`, isInline: true, styles: [":host ::ng-deep>*{display:inline-flex}\n"], dependencies: [{ kind: "component", type: Spinner, selector: "ksd-spinner", inputs: ["aria-label", "data-size", "data-color", "aria-hidden"] }] });
|
|
165
|
+
}
|
|
166
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Button, decorators: [{
|
|
167
|
+
type: Component,
|
|
168
|
+
args: [{ selector: 'button[ksd-button], a[ksd-button]', hostDirectives: [
|
|
169
|
+
{
|
|
170
|
+
directive: CommonInputs,
|
|
171
|
+
inputs: ['data-size', 'data-color'],
|
|
172
|
+
},
|
|
173
|
+
], imports: [Spinner], host: {
|
|
174
|
+
class: 'ds-button',
|
|
175
|
+
type: 'button',
|
|
176
|
+
'[attr.data-variant]': 'variant()',
|
|
177
|
+
'[attr.data-icon]': 'icon() || null',
|
|
178
|
+
'[attr.disabled]': 'disabled() ? true : null',
|
|
179
|
+
'[attr.aria-busy]': 'loading() ? true : null',
|
|
180
|
+
}, template: `
|
|
181
|
+
@if (loading()) {
|
|
182
|
+
<ksd-spinner aria-hidden="true" />
|
|
183
|
+
}
|
|
184
|
+
<ng-content />
|
|
185
|
+
`, styles: [":host ::ng-deep>*{display:inline-flex}\n"] }]
|
|
186
|
+
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }] } });
|
|
187
|
+
|
|
188
|
+
class Card {
|
|
189
|
+
/**
|
|
190
|
+
* Change the background color of the card
|
|
191
|
+
* @default 'default'
|
|
192
|
+
*/
|
|
193
|
+
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
|
|
194
|
+
elementRef = inject(ElementRef);
|
|
195
|
+
projectedLink() {
|
|
196
|
+
const el = this.elementRef.nativeElement;
|
|
197
|
+
return el?.querySelector('h1 a, h2 a, h3 a, h4 a, h5 a, h6 a');
|
|
198
|
+
}
|
|
199
|
+
handleClick = (event) => {
|
|
200
|
+
const link = this.projectedLink();
|
|
201
|
+
if (!link)
|
|
202
|
+
return;
|
|
203
|
+
if (event.metaKey || event.ctrlKey) {
|
|
204
|
+
window.open(link.href, '_blank', 'noopener,noreferrer');
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
link.click();
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Card, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
211
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: Card, isStandalone: true, selector: "[ksd-card]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "handleClick($event)" }, properties: { "attr.data-variant": "variant()" }, classAttribute: "ds-card" }, hostDirectives: [{ directive: CommonInputs, inputs: ["data-size", "data-size", "data-color", "data-color"] }], ngImport: i0, template: ` <ng-content /> `, isInline: true });
|
|
212
|
+
}
|
|
213
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Card, decorators: [{
|
|
214
|
+
type: Component,
|
|
215
|
+
args: [{
|
|
216
|
+
selector: '[ksd-card]',
|
|
217
|
+
template: ` <ng-content /> `,
|
|
218
|
+
hostDirectives: [
|
|
219
|
+
{
|
|
220
|
+
directive: CommonInputs,
|
|
221
|
+
inputs: ['data-size', 'data-color'],
|
|
222
|
+
},
|
|
223
|
+
],
|
|
224
|
+
host: {
|
|
225
|
+
class: 'ds-card',
|
|
226
|
+
'[attr.data-variant]': 'variant()',
|
|
227
|
+
'(click)': 'handleClick($event)',
|
|
228
|
+
},
|
|
229
|
+
}]
|
|
230
|
+
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }] } });
|
|
231
|
+
|
|
232
|
+
class CardBlock {
|
|
233
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CardBlock, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
234
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: CardBlock, isStandalone: true, selector: "[ksd-card-block]", host: { classAttribute: "ds-card__block" }, ngImport: i0, template: `<ng-content />`, isInline: true });
|
|
235
|
+
}
|
|
236
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CardBlock, decorators: [{
|
|
237
|
+
type: Component,
|
|
238
|
+
args: [{
|
|
239
|
+
selector: '[ksd-card-block]',
|
|
240
|
+
host: {
|
|
241
|
+
class: 'ds-card__block',
|
|
242
|
+
},
|
|
243
|
+
template: `<ng-content />`,
|
|
244
|
+
}]
|
|
245
|
+
}] });
|
|
246
|
+
|
|
247
|
+
class Details {
|
|
248
|
+
dataSize = input(undefined, ...(ngDevMode ? [{ debugName: "dataSize",
|
|
249
|
+
// eslint-disable-next-line @angular-eslint/no-input-rename
|
|
250
|
+
alias: 'data-size' }] : [{
|
|
251
|
+
// eslint-disable-next-line @angular-eslint/no-input-rename
|
|
252
|
+
alias: 'data-size',
|
|
253
|
+
}]));
|
|
254
|
+
dataColor = input(undefined, ...(ngDevMode ? [{ debugName: "dataColor",
|
|
255
|
+
// eslint-disable-next-line @angular-eslint/no-input-rename
|
|
256
|
+
alias: 'data-color' }] : [{
|
|
257
|
+
// eslint-disable-next-line @angular-eslint/no-input-rename
|
|
258
|
+
alias: 'data-color',
|
|
259
|
+
}]));
|
|
260
|
+
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
|
|
261
|
+
defaultOpen = input(false, ...(ngDevMode ? [{ debugName: "defaultOpen" }] : []));
|
|
262
|
+
open = input(undefined, ...(ngDevMode ? [{ debugName: "open" }] : []));
|
|
263
|
+
toggled = output();
|
|
264
|
+
detailsRef = viewChild('detailsRef', ...(ngDevMode ? [{ debugName: "detailsRef" }] : []));
|
|
265
|
+
onToggle(event) {
|
|
266
|
+
const details = this.detailsRef()?.nativeElement;
|
|
267
|
+
if (details && details.open !== this.open()) {
|
|
268
|
+
this.toggled.emit(event);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Details, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
272
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.9", type: Details, isStandalone: true, selector: "ksd-details", inputs: { dataSize: { classPropertyName: "dataSize", publicName: "data-size", isSignal: true, isRequired: false, transformFunction: null }, dataColor: { classPropertyName: "dataColor", publicName: "data-color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, defaultOpen: { classPropertyName: "defaultOpen", publicName: "defaultOpen", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggled: "toggled" }, viewQueries: [{ propertyName: "detailsRef", first: true, predicate: ["detailsRef"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
273
|
+
<u-details
|
|
274
|
+
#detailsRef
|
|
275
|
+
class="ds-details"
|
|
276
|
+
[attr.data-variant]="variant()"
|
|
277
|
+
[attr.open]="(open() ?? defaultOpen()) || undefined"
|
|
278
|
+
[attr.data-color]="dataColor()"
|
|
279
|
+
[attr.data-size]="dataSize()"
|
|
280
|
+
(toggle)="onToggle($event)"
|
|
281
|
+
>
|
|
282
|
+
<u-summary>
|
|
283
|
+
<ng-content select="ksd-details-summary" />
|
|
284
|
+
</u-summary>
|
|
285
|
+
<div>
|
|
286
|
+
<ng-content select="ksd-details-content" />
|
|
287
|
+
</div>
|
|
288
|
+
</u-details>
|
|
289
|
+
`, isInline: true, styles: [".ds-card>:host(:last-of-type)>.ds-details{border-bottom:0}.ds-card>:host(:first-of-type)>.ds-details{border-top:0}:host(:not(:first-of-type))>.ds-details{border-top:0;margin-top:0}\n"] });
|
|
290
|
+
}
|
|
291
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Details, decorators: [{
|
|
292
|
+
type: Component,
|
|
293
|
+
args: [{ selector: 'ksd-details', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: `
|
|
294
|
+
<u-details
|
|
295
|
+
#detailsRef
|
|
296
|
+
class="ds-details"
|
|
297
|
+
[attr.data-variant]="variant()"
|
|
298
|
+
[attr.open]="(open() ?? defaultOpen()) || undefined"
|
|
299
|
+
[attr.data-color]="dataColor()"
|
|
300
|
+
[attr.data-size]="dataSize()"
|
|
301
|
+
(toggle)="onToggle($event)"
|
|
302
|
+
>
|
|
303
|
+
<u-summary>
|
|
304
|
+
<ng-content select="ksd-details-summary" />
|
|
305
|
+
</u-summary>
|
|
306
|
+
<div>
|
|
307
|
+
<ng-content select="ksd-details-content" />
|
|
308
|
+
</div>
|
|
309
|
+
</u-details>
|
|
310
|
+
`, styles: [".ds-card>:host(:last-of-type)>.ds-details{border-bottom:0}.ds-card>:host(:first-of-type)>.ds-details{border-top:0}:host(:not(:first-of-type))>.ds-details{border-top:0;margin-top:0}\n"] }]
|
|
311
|
+
}], propDecorators: { dataSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "data-size", required: false }] }], dataColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "data-color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], defaultOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultOpen", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], toggled: [{ type: i0.Output, args: ["toggled"] }], detailsRef: [{ type: i0.ViewChild, args: ['detailsRef', { isSignal: true }] }] } });
|
|
312
|
+
|
|
313
|
+
class DetailsContent {
|
|
314
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: DetailsContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
315
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: DetailsContent, isStandalone: true, selector: "ksd-details-content", ngImport: i0, template: `<ng-content />`, isInline: true });
|
|
316
|
+
}
|
|
317
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: DetailsContent, decorators: [{
|
|
318
|
+
type: Component,
|
|
319
|
+
args: [{
|
|
320
|
+
selector: 'ksd-details-content',
|
|
321
|
+
template: `<ng-content />`,
|
|
322
|
+
}]
|
|
323
|
+
}] });
|
|
324
|
+
|
|
325
|
+
class DetailsSummary {
|
|
326
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: DetailsSummary, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
327
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: DetailsSummary, isStandalone: true, selector: "ksd-details-summary", ngImport: i0, template: `<ng-content />`, isInline: true });
|
|
328
|
+
}
|
|
329
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: DetailsSummary, decorators: [{
|
|
330
|
+
type: Component,
|
|
331
|
+
args: [{
|
|
332
|
+
selector: 'ksd-details-summary',
|
|
333
|
+
template: `<ng-content />`,
|
|
334
|
+
}]
|
|
335
|
+
}] });
|
|
336
|
+
|
|
337
|
+
class FieldState {
|
|
338
|
+
/**
|
|
339
|
+
* Whether the field counter has exceeded its limit
|
|
340
|
+
*/
|
|
341
|
+
hasExceededCounter = signal(false, ...(ngDevMode ? [{ debugName: "hasExceededCounter" }] : []));
|
|
342
|
+
/**
|
|
343
|
+
* Whether the field has errors projected from the outside
|
|
344
|
+
*/
|
|
345
|
+
hasProjectedErrors = signal(false, ...(ngDevMode ? [{ debugName: "hasProjectedErrors" }] : []));
|
|
346
|
+
/**
|
|
347
|
+
* Whether the field has any errors associated with it
|
|
348
|
+
*/
|
|
349
|
+
hasError = computed(() => this.hasExceededCounter() || this.hasProjectedErrors(), ...(ngDevMode ? [{ debugName: "hasError" }] : []));
|
|
350
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldState, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
351
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldState });
|
|
352
|
+
}
|
|
353
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldState, decorators: [{
|
|
354
|
+
type: Injectable
|
|
355
|
+
}] });
|
|
356
|
+
|
|
357
|
+
class Input {
|
|
358
|
+
/**
|
|
359
|
+
* The value of the input
|
|
360
|
+
*/
|
|
361
|
+
value = signal('', ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
362
|
+
/**
|
|
363
|
+
* Whether the input is readonly
|
|
364
|
+
*/
|
|
365
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
366
|
+
/**
|
|
367
|
+
* Disables element
|
|
368
|
+
*/
|
|
369
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
370
|
+
/**
|
|
371
|
+
* Whether the element is invalid.
|
|
372
|
+
*/
|
|
373
|
+
ariaInvalid = input(false, ...(ngDevMode ? [{ debugName: "ariaInvalid", transform: booleanAttribute,
|
|
374
|
+
alias: 'aria-invalid' }] : [{
|
|
375
|
+
transform: booleanAttribute,
|
|
376
|
+
alias: 'aria-invalid',
|
|
377
|
+
}]));
|
|
378
|
+
/**
|
|
379
|
+
* Displays a character counter. pass a number to set a limit.
|
|
380
|
+
*/
|
|
381
|
+
counter = input(0, ...(ngDevMode ? [{ debugName: "counter", transform: numberAttribute }] : [{ transform: numberAttribute }]));
|
|
382
|
+
fieldState = inject(FieldState, { optional: true });
|
|
383
|
+
onClick(event) {
|
|
384
|
+
if (this.readonly()) {
|
|
385
|
+
event.preventDefault();
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Input, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
389
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.9", type: Input, isStandalone: true, selector: "input[ksd-input], textarea[ksd-input], select[ksd-input]", inputs: { readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaInvalid: { classPropertyName: "ariaInvalid", publicName: "aria-invalid", isSignal: true, isRequired: false, transformFunction: null }, counter: { classPropertyName: "counter", publicName: "counter", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick($event)", "input": "value.set($event.target.value)" }, properties: { "attr.readonly": "readonly() ? true : null", "attr.disabled": "disabled() ? true : null", "attr.aria-invalid": "ariaInvalid() ? true : (fieldState?.hasError() ? true: null)" }, classAttribute: "ds-input" }, hostDirectives: [{ directive: CommonInputs, inputs: ["data-size", "data-size", "data-color", "data-color"] }], ngImport: i0 });
|
|
390
|
+
}
|
|
391
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Input, decorators: [{
|
|
392
|
+
type: Directive,
|
|
393
|
+
args: [{
|
|
394
|
+
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
395
|
+
selector: 'input[ksd-input], textarea[ksd-input], select[ksd-input]',
|
|
396
|
+
hostDirectives: [
|
|
397
|
+
{
|
|
398
|
+
directive: CommonInputs,
|
|
399
|
+
inputs: ['data-size', 'data-color'],
|
|
400
|
+
},
|
|
401
|
+
],
|
|
402
|
+
host: {
|
|
403
|
+
class: 'ds-input',
|
|
404
|
+
'[attr.readonly]': 'readonly() ? true : null',
|
|
405
|
+
'[attr.disabled]': 'disabled() ? true : null',
|
|
406
|
+
'[attr.aria-invalid]': 'ariaInvalid() ? true : (fieldState?.hasError() ? true: null)',
|
|
407
|
+
'(click)': 'onClick($event)',
|
|
408
|
+
'(input)': 'value.set($event.target.value)',
|
|
409
|
+
},
|
|
410
|
+
}]
|
|
411
|
+
}], propDecorators: { readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaInvalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-invalid", required: false }] }], counter: [{ type: i0.Input, args: [{ isSignal: true, alias: "counter", required: false }] }] } });
|
|
412
|
+
|
|
413
|
+
class Label {
|
|
414
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Label, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
415
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: Label, isStandalone: true, selector: "ksd-label", hostDirectives: [{ directive: CommonInputs, inputs: ["data-size", "data-size", "data-color", "data-color"] }], ngImport: i0, template: `
|
|
416
|
+
<!-- eslint-disable @angular-eslint/template/label-has-associated-control -- Fieldobserver handles binding the label to the input -->
|
|
417
|
+
<label class="ds-label"><ng-content /></label>
|
|
418
|
+
`, isInline: true });
|
|
419
|
+
}
|
|
420
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Label, decorators: [{
|
|
421
|
+
type: Component,
|
|
422
|
+
args: [{
|
|
423
|
+
selector: 'ksd-label',
|
|
424
|
+
hostDirectives: [
|
|
425
|
+
{
|
|
426
|
+
directive: CommonInputs,
|
|
427
|
+
inputs: ['data-size', 'data-color'],
|
|
428
|
+
},
|
|
429
|
+
],
|
|
430
|
+
template: `
|
|
431
|
+
<!-- eslint-disable @angular-eslint/template/label-has-associated-control -- Fieldobserver handles binding the label to the input -->
|
|
432
|
+
<label class="ds-label"><ng-content /></label>
|
|
433
|
+
`,
|
|
434
|
+
}]
|
|
435
|
+
}] });
|
|
436
|
+
|
|
437
|
+
class ValidationMessage {
|
|
438
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ValidationMessage, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
439
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.9", type: ValidationMessage, isStandalone: true, selector: "[ksd-validation-message]", host: { attributes: { "data-field": "validation" }, classAttribute: "ds-validation-message" }, ngImport: i0 });
|
|
440
|
+
}
|
|
441
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ValidationMessage, decorators: [{
|
|
442
|
+
type: Directive,
|
|
443
|
+
args: [{
|
|
444
|
+
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
445
|
+
selector: '[ksd-validation-message]',
|
|
446
|
+
host: {
|
|
447
|
+
class: 'ds-validation-message',
|
|
448
|
+
'data-field': 'validation',
|
|
449
|
+
},
|
|
450
|
+
}]
|
|
451
|
+
}] });
|
|
452
|
+
|
|
453
|
+
class FieldCounter {
|
|
454
|
+
/**
|
|
455
|
+
* The maximum allowed characters.
|
|
456
|
+
*
|
|
457
|
+
**/
|
|
458
|
+
limit = input.required(...(ngDevMode ? [{ debugName: "limit" }] : []));
|
|
459
|
+
/**
|
|
460
|
+
* How many characters have been typed.
|
|
461
|
+
*
|
|
462
|
+
**/
|
|
463
|
+
count = input.required(...(ngDevMode ? [{ debugName: "count" }] : []));
|
|
464
|
+
remainder = computed(() => this.limit() - this.count(), ...(ngDevMode ? [{ debugName: "remainder" }] : []));
|
|
465
|
+
excessCount = computed(() => Math.abs(this.remainder()), ...(ngDevMode ? [{ debugName: "excessCount" }] : []));
|
|
466
|
+
hasExceededLimit = computed(() => this.count() > this.limit(), ...(ngDevMode ? [{ debugName: "hasExceededLimit" }] : []));
|
|
467
|
+
fieldState = inject(FieldState);
|
|
468
|
+
constructor() {
|
|
469
|
+
effect(() => {
|
|
470
|
+
this.fieldState.hasExceededCounter.set(this.hasExceededLimit());
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldCounter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
474
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: FieldCounter, isStandalone: true, selector: "ksd-field-counter", inputs: { limit: { classPropertyName: "limit", publicName: "limit", isSignal: true, isRequired: true, transformFunction: null }, count: { classPropertyName: "count", publicName: "count", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
475
|
+
<div data-field="description" class="ds-sr-only" aria-live="polite">
|
|
476
|
+
@if (hasExceededLimit()) {
|
|
477
|
+
{{ excessCount() }} tegn for mye
|
|
478
|
+
}
|
|
479
|
+
</div>
|
|
480
|
+
@if (hasExceededLimit()) {
|
|
481
|
+
<p ksd-validation-message>{{ excessCount() }} tegn for mye</p>
|
|
482
|
+
} @else {
|
|
483
|
+
<p data-field="validation">{{ remainder() }} tegn igjen</p>
|
|
484
|
+
}
|
|
485
|
+
`, isInline: true, styles: [":host>*{margin-top:var(--dsc-field-content-spacing)}\n"], dependencies: [{ kind: "directive", type: ValidationMessage, selector: "[ksd-validation-message]" }] });
|
|
486
|
+
}
|
|
487
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldCounter, decorators: [{
|
|
488
|
+
type: Component,
|
|
489
|
+
args: [{ selector: 'ksd-field-counter', imports: [ValidationMessage], template: `
|
|
490
|
+
<div data-field="description" class="ds-sr-only" aria-live="polite">
|
|
491
|
+
@if (hasExceededLimit()) {
|
|
492
|
+
{{ excessCount() }} tegn for mye
|
|
493
|
+
}
|
|
494
|
+
</div>
|
|
495
|
+
@if (hasExceededLimit()) {
|
|
496
|
+
<p ksd-validation-message>{{ excessCount() }} tegn for mye</p>
|
|
497
|
+
} @else {
|
|
498
|
+
<p data-field="validation">{{ remainder() }} tegn igjen</p>
|
|
499
|
+
}
|
|
500
|
+
`, styles: [":host>*{margin-top:var(--dsc-field-content-spacing)}\n"] }]
|
|
501
|
+
}], ctorParameters: () => [], propDecorators: { limit: [{ type: i0.Input, args: [{ isSignal: true, alias: "limit", required: true }] }], count: [{ type: i0.Input, args: [{ isSignal: true, alias: "count", required: true }] }] } });
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Lifted from Designsystemet core repo.
|
|
505
|
+
* Takes care of binding ids, labels and aria-describedby attributes
|
|
506
|
+
*
|
|
507
|
+
* @param fieldElement - The field element to observe
|
|
508
|
+
* @returns A function to disconnect the observer
|
|
509
|
+
* */
|
|
510
|
+
function fieldObserver(fieldElement) {
|
|
511
|
+
if (!fieldElement)
|
|
512
|
+
return;
|
|
513
|
+
const elements = new Map();
|
|
514
|
+
const typeCounter = new Map(); // Track count for each data-field type
|
|
515
|
+
const uuid = `:${Date.now().toString(36)}${Math.random().toString(36).slice(2, 5)}`;
|
|
516
|
+
let input = null;
|
|
517
|
+
let describedby = '';
|
|
518
|
+
const process = (mutations) => {
|
|
519
|
+
const changed = [];
|
|
520
|
+
const removed = [];
|
|
521
|
+
// Merge MutationRecords
|
|
522
|
+
for (const mutation of mutations) {
|
|
523
|
+
if (mutation.attributeName)
|
|
524
|
+
changed.push(mutation.target ?? fieldElement);
|
|
525
|
+
// @ts-expect-error - addedNodes is not typed
|
|
526
|
+
changed.push(...(mutation.addedNodes || []));
|
|
527
|
+
removed.push(...(mutation.removedNodes || []));
|
|
528
|
+
}
|
|
529
|
+
// Register elements
|
|
530
|
+
for (const el of changed) {
|
|
531
|
+
if (!isElement(el))
|
|
532
|
+
continue;
|
|
533
|
+
if (isLabel(el))
|
|
534
|
+
elements.set(el, el.htmlFor);
|
|
535
|
+
else if (el.hasAttribute('data-field'))
|
|
536
|
+
elements.set(el, el.id);
|
|
537
|
+
else if (isInputLike(el)) {
|
|
538
|
+
input = el;
|
|
539
|
+
describedby = el.getAttribute('aria-describedby') || '';
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
// Reset removed elements
|
|
543
|
+
for (const el of removed) {
|
|
544
|
+
if (!isElement(el))
|
|
545
|
+
continue;
|
|
546
|
+
if (input === el)
|
|
547
|
+
input = null;
|
|
548
|
+
if (elements.has(el)) {
|
|
549
|
+
setAttr(el, isLabel(el) ? 'for' : 'id', elements.get(el));
|
|
550
|
+
elements.delete(el);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
// Connect elements
|
|
554
|
+
const describedbyIds = [describedby]; // Keep original aria-describedby
|
|
555
|
+
const inputId = input?.id || uuid;
|
|
556
|
+
// Reset type counters since we reprocess all elements
|
|
557
|
+
typeCounter.clear();
|
|
558
|
+
for (const [el, value] of elements) {
|
|
559
|
+
const descriptionType = el.getAttribute('data-field');
|
|
560
|
+
let id;
|
|
561
|
+
if (descriptionType) {
|
|
562
|
+
// Increment type counter for this type
|
|
563
|
+
const count = (typeCounter.get(descriptionType) || 0) + 1;
|
|
564
|
+
typeCounter.set(descriptionType, count);
|
|
565
|
+
id = `${inputId}:${descriptionType}:${count}`;
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
id = inputId;
|
|
569
|
+
}
|
|
570
|
+
if (!value)
|
|
571
|
+
setAttr(el, isLabel(el) ? 'for' : 'id', id); // Ensure we have a value
|
|
572
|
+
if (descriptionType === 'validation')
|
|
573
|
+
describedbyIds.unshift(el.id); // Validations to the front
|
|
574
|
+
else if (descriptionType)
|
|
575
|
+
describedbyIds.push(el.id); // Other descriptions to the back
|
|
576
|
+
}
|
|
577
|
+
setAttr(input, 'id', inputId);
|
|
578
|
+
setAttr(input, 'aria-describedby', describedbyIds.join(' ').trim());
|
|
579
|
+
};
|
|
580
|
+
const observer = createOptimizedMutationObserver(process);
|
|
581
|
+
observer.observe(fieldElement, {
|
|
582
|
+
attributeFilter: ['id', 'for', 'aria-describedby'],
|
|
583
|
+
attributes: true,
|
|
584
|
+
childList: true,
|
|
585
|
+
subtree: true,
|
|
586
|
+
});
|
|
587
|
+
process([{ addedNodes: fieldElement.querySelectorAll('*') }]); // Initial setup
|
|
588
|
+
observer.takeRecords(); // Clear initial setup queue
|
|
589
|
+
return () => observer.disconnect();
|
|
590
|
+
}
|
|
591
|
+
// Utilities
|
|
592
|
+
const isElement = (node) => node instanceof Element;
|
|
593
|
+
const isLabel = (node) => node instanceof HTMLLabelElement;
|
|
594
|
+
const isInputLike = (node) => node instanceof HTMLElement &&
|
|
595
|
+
'validity' in node &&
|
|
596
|
+
!(node instanceof HTMLButtonElement); // Matches input, textarea, select and form accosiated custom elements
|
|
597
|
+
const setAttr = (el, name, value) => value ? el?.setAttribute(name, value) : el?.removeAttribute(name);
|
|
598
|
+
// Speed up MutationObserver by debouncing, clearing internal queue after changes and only running when page is visible
|
|
599
|
+
function createOptimizedMutationObserver(callback) {
|
|
600
|
+
const queue = [];
|
|
601
|
+
const observer = new MutationObserver((mutations) => {
|
|
602
|
+
if (!queue.length)
|
|
603
|
+
requestAnimationFrame(process);
|
|
604
|
+
queue.push(...mutations);
|
|
605
|
+
});
|
|
606
|
+
const process = () => {
|
|
607
|
+
callback(queue, observer);
|
|
608
|
+
queue.length = 0; // Reset queue
|
|
609
|
+
observer.takeRecords(); // Clear queue due to DOM changes in callback
|
|
610
|
+
};
|
|
611
|
+
return observer;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* Use the Field component to connect inputs and labels
|
|
616
|
+
*/
|
|
617
|
+
class Field {
|
|
618
|
+
/**
|
|
619
|
+
* Position of toggle inputs (radio, checkbox, switch) in field
|
|
620
|
+
* @default start
|
|
621
|
+
*/
|
|
622
|
+
position = input('start', ...(ngDevMode ? [{ debugName: "position" }] : []));
|
|
623
|
+
fieldState = inject(FieldState);
|
|
624
|
+
input = contentChild(Input, ...(ngDevMode ? [{ debugName: "input" }] : []));
|
|
625
|
+
label = contentChild(Label, ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
626
|
+
projectedErrors = contentChildren(ValidationMessage, ...(ngDevMode ? [{ debugName: "projectedErrors" }] : []));
|
|
627
|
+
el = inject(ElementRef);
|
|
628
|
+
count = computed(() => this.input()?.value().length, ...(ngDevMode ? [{ debugName: "count" }] : []));
|
|
629
|
+
limit = computed(() => this.input()?.counter(), ...(ngDevMode ? [{ debugName: "limit" }] : []));
|
|
630
|
+
hasCounter = computed(() => this.limit(), ...(ngDevMode ? [{ debugName: "hasCounter" }] : []));
|
|
631
|
+
constructor() {
|
|
632
|
+
afterNextRender(() => {
|
|
633
|
+
fieldObserver(this.el.nativeElement);
|
|
634
|
+
});
|
|
635
|
+
effect(() => {
|
|
636
|
+
this.fieldState.hasProjectedErrors.set(this.projectedErrors().length > 0);
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Field, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
640
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: Field, isStandalone: true, selector: "ksd-field", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.dataPosition": "position()" }, classAttribute: "ds-field" }, providers: [FieldState], queries: [{ propertyName: "input", first: true, predicate: Input, descendants: true, isSignal: true }, { propertyName: "label", first: true, predicate: Label, descendants: true, isSignal: true }, { propertyName: "projectedErrors", predicate: ValidationMessage, isSignal: true }], hostDirectives: [{ directive: CommonInputs, inputs: ["data-size", "data-size", "data-color", "data-color"] }], ngImport: i0, template: `
|
|
641
|
+
<ng-content />
|
|
642
|
+
@if (hasCounter()) {
|
|
643
|
+
<ksd-field-counter [limit]="limit() ?? 0" [count]="count() ?? 0" />
|
|
644
|
+
}
|
|
645
|
+
`, isInline: true, dependencies: [{ kind: "component", type: FieldCounter, selector: "ksd-field-counter", inputs: ["limit", "count"] }] });
|
|
646
|
+
}
|
|
647
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Field, decorators: [{
|
|
648
|
+
type: Component,
|
|
649
|
+
args: [{
|
|
650
|
+
selector: 'ksd-field',
|
|
651
|
+
hostDirectives: [
|
|
652
|
+
{
|
|
653
|
+
directive: CommonInputs,
|
|
654
|
+
inputs: ['data-size', 'data-color'],
|
|
655
|
+
},
|
|
656
|
+
],
|
|
657
|
+
host: {
|
|
658
|
+
class: 'ds-field',
|
|
659
|
+
'[attr.dataPosition]': 'position()',
|
|
660
|
+
},
|
|
661
|
+
template: `
|
|
662
|
+
<ng-content />
|
|
663
|
+
@if (hasCounter()) {
|
|
664
|
+
<ksd-field-counter [limit]="limit() ?? 0" [count]="count() ?? 0" />
|
|
665
|
+
}
|
|
666
|
+
`,
|
|
667
|
+
imports: [FieldCounter],
|
|
668
|
+
providers: [FieldState],
|
|
669
|
+
}]
|
|
670
|
+
}], ctorParameters: () => [], propDecorators: { position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], input: [{ type: i0.ContentChild, args: [i0.forwardRef(() => Input), { isSignal: true }] }], label: [{ type: i0.ContentChild, args: [i0.forwardRef(() => Label), { isSignal: true }] }], projectedErrors: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => ValidationMessage), { isSignal: true }] }] } });
|
|
671
|
+
|
|
672
|
+
class FieldDescription {
|
|
673
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldDescription, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
674
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: FieldDescription, isStandalone: true, selector: "[ksd-field-description]", host: { attributes: { "data-field": "description" } }, ngImport: i0, template: `<ng-content />`, isInline: true });
|
|
675
|
+
}
|
|
676
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldDescription, decorators: [{
|
|
677
|
+
type: Component,
|
|
678
|
+
args: [{
|
|
679
|
+
selector: '[ksd-field-description]',
|
|
680
|
+
host: {
|
|
681
|
+
'data-field': 'description',
|
|
682
|
+
},
|
|
683
|
+
template: `<ng-content />`,
|
|
684
|
+
}]
|
|
685
|
+
}] });
|
|
686
|
+
|
|
687
|
+
class FieldError {
|
|
688
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldError, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
689
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: FieldError, isStandalone: true, selector: "[ksd-error]", hostDirectives: [{ directive: ValidationMessage }], ngImport: i0, template: `<ng-content />`, isInline: true });
|
|
690
|
+
}
|
|
691
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldError, decorators: [{
|
|
692
|
+
type: Component,
|
|
693
|
+
args: [{
|
|
694
|
+
selector: '[ksd-error]',
|
|
695
|
+
template: `<ng-content />`,
|
|
696
|
+
hostDirectives: [
|
|
697
|
+
{
|
|
698
|
+
directive: ValidationMessage,
|
|
699
|
+
},
|
|
700
|
+
],
|
|
701
|
+
}]
|
|
702
|
+
}] });
|
|
703
|
+
|
|
704
|
+
class Fieldset {
|
|
705
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Fieldset, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
706
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: Fieldset, isStandalone: true, selector: "fieldset[ksd-fieldset]", host: { attributes: { "role": "fieldset" }, classAttribute: "ds-fieldset" }, ngImport: i0, template: ` <ng-content /> `, isInline: true });
|
|
707
|
+
}
|
|
708
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Fieldset, decorators: [{
|
|
709
|
+
type: Component,
|
|
710
|
+
args: [{
|
|
711
|
+
selector: 'fieldset[ksd-fieldset]',
|
|
712
|
+
host: {
|
|
713
|
+
role: 'fieldset',
|
|
714
|
+
class: 'ds-fieldset',
|
|
715
|
+
},
|
|
716
|
+
template: ` <ng-content /> `,
|
|
717
|
+
}]
|
|
718
|
+
}] });
|
|
719
|
+
|
|
720
|
+
class FieldsetDescription {
|
|
721
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldsetDescription, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
722
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: FieldsetDescription, isStandalone: true, selector: "p[ksd-fieldset-description]", ngImport: i0, template: `<ng-content />`, isInline: true });
|
|
723
|
+
}
|
|
724
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldsetDescription, decorators: [{
|
|
725
|
+
type: Component,
|
|
726
|
+
args: [{
|
|
727
|
+
selector: 'p[ksd-fieldset-description]',
|
|
728
|
+
template: `<ng-content />`,
|
|
729
|
+
host: {},
|
|
730
|
+
}]
|
|
731
|
+
}] });
|
|
732
|
+
|
|
733
|
+
class FieldsetLegend {
|
|
734
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldsetLegend, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
735
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: FieldsetLegend, isStandalone: true, selector: "legend[ksd-fieldset-legend]", host: { attributes: { "role": "legend" }, classAttribute: "ds-label" }, ngImport: i0, template: ` <ng-content /> `, isInline: true });
|
|
736
|
+
}
|
|
737
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FieldsetLegend, decorators: [{
|
|
738
|
+
type: Component,
|
|
739
|
+
args: [{
|
|
740
|
+
selector: 'legend[ksd-fieldset-legend]',
|
|
741
|
+
host: {
|
|
742
|
+
role: 'legend',
|
|
743
|
+
class: 'ds-label',
|
|
744
|
+
},
|
|
745
|
+
template: ` <ng-content /> `,
|
|
746
|
+
}]
|
|
747
|
+
}] });
|
|
748
|
+
|
|
749
|
+
class Paragraph {
|
|
750
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Paragraph, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
751
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: Paragraph, isStandalone: true, selector: "p[ksd-paragraph]", host: { classAttribute: "ds-paragraph" }, ngImport: i0, template: `<ng-content />`, isInline: true });
|
|
752
|
+
}
|
|
753
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Paragraph, decorators: [{
|
|
754
|
+
type: Component,
|
|
755
|
+
args: [{
|
|
756
|
+
selector: 'p[ksd-paragraph]',
|
|
757
|
+
template: `<ng-content />`,
|
|
758
|
+
host: {
|
|
759
|
+
class: 'ds-paragraph',
|
|
760
|
+
},
|
|
761
|
+
}]
|
|
762
|
+
}] });
|
|
763
|
+
|
|
764
|
+
/* eslint-disable @angular-eslint/no-input-rename */
|
|
765
|
+
class Popover {
|
|
766
|
+
// use popoverId instead of id since id will be put on the angular element and not the popover-div
|
|
767
|
+
popoverId = input.required(...(ngDevMode ? [{ debugName: "popoverId" }] : []));
|
|
768
|
+
placement = input('top', ...(ngDevMode ? [{ debugName: "placement" }] : []));
|
|
769
|
+
autoPlacement = input(true, ...(ngDevMode ? [{ debugName: "autoPlacement", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
770
|
+
// for controlled component
|
|
771
|
+
open = input(undefined, ...(ngDevMode ? [{ debugName: "open", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
772
|
+
/*
|
|
773
|
+
the naming here is different from Designsystemet
|
|
774
|
+
since we need to use outputs for onOpen and onClose
|
|
775
|
+
*/
|
|
776
|
+
triggeredClose = output();
|
|
777
|
+
triggeredOpen = output();
|
|
778
|
+
internalOpen = signal(false, ...(ngDevMode ? [{ debugName: "internalOpen" }] : []));
|
|
779
|
+
controlledOpen = computed(() => this.open() ?? this.internalOpen(), ...(ngDevMode ? [{ debugName: "controlledOpen" }] : []));
|
|
780
|
+
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
|
|
781
|
+
dataSize = input('md', ...(ngDevMode ? [{ debugName: "dataSize", alias: 'data-size' }] : [{ alias: 'data-size' }]));
|
|
782
|
+
dataColor = input('neutral', ...(ngDevMode ? [{ debugName: "dataColor", alias: 'data-color' }] : [{
|
|
783
|
+
alias: 'data-color',
|
|
784
|
+
}]));
|
|
785
|
+
popoverRef = viewChild('myPopover', ...(ngDevMode ? [{ debugName: "popoverRef" }] : []));
|
|
786
|
+
// enable controlled component
|
|
787
|
+
controlledComponent = effect((onCleanup) => {
|
|
788
|
+
const popover = this.popoverRef()?.nativeElement;
|
|
789
|
+
const handleClick = (event) => {
|
|
790
|
+
const el = event.target;
|
|
791
|
+
const isTrigger = el?.closest?.(`[popovertarget="${this.popoverId()}"]`);
|
|
792
|
+
const isOutside = !isTrigger && !popover?.contains(el);
|
|
793
|
+
if (isTrigger) {
|
|
794
|
+
event.preventDefault(); // Prevent native Popover API
|
|
795
|
+
this.internalOpen.update((open) => !open);
|
|
796
|
+
this.triggeredOpen.emit();
|
|
797
|
+
}
|
|
798
|
+
if (isOutside) {
|
|
799
|
+
this.internalOpen.set(false);
|
|
800
|
+
this.triggeredClose.emit();
|
|
801
|
+
}
|
|
802
|
+
};
|
|
803
|
+
const handleKeydown = (event) => {
|
|
804
|
+
if (event.key !== 'Escape' || !this.controlledOpen())
|
|
805
|
+
return;
|
|
806
|
+
event.preventDefault(); // Prevent closing fullscreen in Safari
|
|
807
|
+
this.internalOpen.set(false);
|
|
808
|
+
this.triggeredClose.emit();
|
|
809
|
+
};
|
|
810
|
+
popover?.togglePopover?.(this.controlledOpen());
|
|
811
|
+
document.addEventListener('click', handleClick, true); // Use capture to execute before React event API
|
|
812
|
+
document.addEventListener('keydown', handleKeydown);
|
|
813
|
+
onCleanup(() => {
|
|
814
|
+
document.removeEventListener('click', handleClick, true);
|
|
815
|
+
document.removeEventListener('keydown', handleKeydown);
|
|
816
|
+
});
|
|
817
|
+
}, ...(ngDevMode ? [{ debugName: "controlledComponent" }] : [{}]));
|
|
818
|
+
positionPopover = effect(() => {
|
|
819
|
+
const popover = this.popoverRef()?.nativeElement;
|
|
820
|
+
const trigger = document.querySelector(`[popovertarget="${this.popoverId()}"]`);
|
|
821
|
+
const placement = this.placement();
|
|
822
|
+
if (popover && trigger && this.controlledOpen()) {
|
|
823
|
+
autoUpdate(trigger, popover, () => {
|
|
824
|
+
computePosition(trigger, popover, {
|
|
825
|
+
placement,
|
|
826
|
+
strategy: 'fixed',
|
|
827
|
+
middleware: [
|
|
828
|
+
offset((data) => {
|
|
829
|
+
// get pseudo element arrow size
|
|
830
|
+
const styles = getComputedStyle(data.elements.floating, '::before');
|
|
831
|
+
return parseFloat(styles.height);
|
|
832
|
+
}),
|
|
833
|
+
...(this.autoPlacement()
|
|
834
|
+
? [flip({ fallbackAxisSideDirection: 'start' }), shift()]
|
|
835
|
+
: []),
|
|
836
|
+
this.arrowPseudoElement,
|
|
837
|
+
],
|
|
838
|
+
}).then(({ x, y }) => {
|
|
839
|
+
popover.style.translate = `${x}px ${y}px`;
|
|
840
|
+
});
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
}, ...(ngDevMode ? [{ debugName: "positionPopover" }] : [{}]));
|
|
844
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
845
|
+
arrowPseudoElement = {
|
|
846
|
+
name: 'ArrowPseudoElement',
|
|
847
|
+
fn(data) {
|
|
848
|
+
const { elements, rects, placement } = data;
|
|
849
|
+
let arrowX = `${Math.round(rects.reference.width / 2 + rects.reference.x - data.x)}px`;
|
|
850
|
+
let arrowY = `${Math.round(rects.reference.height / 2 + rects.reference.y - data.y)}px`;
|
|
851
|
+
if (rects.reference.width > rects.floating.width) {
|
|
852
|
+
arrowX = `${Math.round(rects.floating.width / 2)}px`;
|
|
853
|
+
}
|
|
854
|
+
if (rects.reference.height > rects.floating.height) {
|
|
855
|
+
arrowY = `${Math.round(rects.floating.height / 2)}px`;
|
|
856
|
+
}
|
|
857
|
+
switch (placement.split('-')[0]) {
|
|
858
|
+
case 'top':
|
|
859
|
+
arrowY = '100%';
|
|
860
|
+
break;
|
|
861
|
+
case 'right':
|
|
862
|
+
arrowX = '0';
|
|
863
|
+
break;
|
|
864
|
+
case 'bottom':
|
|
865
|
+
arrowY = '0';
|
|
866
|
+
break;
|
|
867
|
+
case 'left':
|
|
868
|
+
arrowX = '100%';
|
|
869
|
+
break;
|
|
870
|
+
}
|
|
871
|
+
elements.floating.setAttribute('data-placement', placement.split('-')[0]); // We only need top/left/right/bottom
|
|
872
|
+
elements.floating.style.setProperty('--ds-popover-arrow-x', arrowX);
|
|
873
|
+
elements.floating.style.setProperty('--ds-popover-arrow-y', arrowY);
|
|
874
|
+
return data;
|
|
875
|
+
},
|
|
876
|
+
};
|
|
877
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Popover, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
878
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: Popover, isStandalone: true, selector: "ksd-popover", inputs: { popoverId: { classPropertyName: "popoverId", publicName: "popoverId", isSignal: true, isRequired: true, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, autoPlacement: { classPropertyName: "autoPlacement", publicName: "autoPlacement", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, dataSize: { classPropertyName: "dataSize", publicName: "data-size", isSignal: true, isRequired: false, transformFunction: null }, dataColor: { classPropertyName: "dataColor", publicName: "data-color", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { triggeredClose: "triggeredClose", triggeredOpen: "triggeredOpen" }, viewQueries: [{ propertyName: "popoverRef", first: true, predicate: ["myPopover"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
879
|
+
<div
|
|
880
|
+
#myPopover
|
|
881
|
+
popover="manual"
|
|
882
|
+
class="ds-popover"
|
|
883
|
+
data-testid="popover"
|
|
884
|
+
[id]="popoverId()"
|
|
885
|
+
[attr.data-size]="dataSize()"
|
|
886
|
+
[attr.data-color]="dataColor()"
|
|
887
|
+
[attr.data-variant]="variant()"
|
|
888
|
+
>
|
|
889
|
+
@if (controlledOpen()) {
|
|
890
|
+
<ng-content />
|
|
891
|
+
}
|
|
892
|
+
</div>
|
|
893
|
+
`, isInline: true });
|
|
894
|
+
}
|
|
895
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Popover, decorators: [{
|
|
896
|
+
type: Component,
|
|
897
|
+
args: [{
|
|
898
|
+
selector: 'ksd-popover',
|
|
899
|
+
template: `
|
|
900
|
+
<div
|
|
901
|
+
#myPopover
|
|
902
|
+
popover="manual"
|
|
903
|
+
class="ds-popover"
|
|
904
|
+
data-testid="popover"
|
|
905
|
+
[id]="popoverId()"
|
|
906
|
+
[attr.data-size]="dataSize()"
|
|
907
|
+
[attr.data-color]="dataColor()"
|
|
908
|
+
[attr.data-variant]="variant()"
|
|
909
|
+
>
|
|
910
|
+
@if (controlledOpen()) {
|
|
911
|
+
<ng-content />
|
|
912
|
+
}
|
|
913
|
+
</div>
|
|
914
|
+
`,
|
|
915
|
+
imports: [],
|
|
916
|
+
}]
|
|
917
|
+
}], propDecorators: { popoverId: [{ type: i0.Input, args: [{ isSignal: true, alias: "popoverId", required: true }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], autoPlacement: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoPlacement", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], triggeredClose: [{ type: i0.Output, args: ["triggeredClose"] }], triggeredOpen: [{ type: i0.Output, args: ["triggeredOpen"] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], dataSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "data-size", required: false }] }], dataColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "data-color", required: false }] }], popoverRef: [{ type: i0.ViewChild, args: ['myPopover', { isSignal: true }] }] } });
|
|
918
|
+
|
|
919
|
+
const logIfDevMode = ({ component, message, }) => {
|
|
920
|
+
if (isDevMode()) {
|
|
921
|
+
console.log(`[${component}] ${message}`);
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* Search input
|
|
927
|
+
*
|
|
928
|
+
* Used within Search to provide a search input.
|
|
929
|
+
*/
|
|
930
|
+
class SearchInput {
|
|
931
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: SearchInput, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
932
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.9", type: SearchInput, isStandalone: true, selector: "input[ksd-search-input]", host: { attributes: { "type": "search", "placeholder": "" }, classAttribute: "ds-input" }, ngImport: i0 });
|
|
933
|
+
}
|
|
934
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: SearchInput, decorators: [{
|
|
935
|
+
type: Directive,
|
|
936
|
+
args: [{
|
|
937
|
+
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
938
|
+
selector: 'input[ksd-search-input]',
|
|
939
|
+
standalone: true,
|
|
940
|
+
host: {
|
|
941
|
+
class: 'ds-input',
|
|
942
|
+
type: 'search',
|
|
943
|
+
placeholder: '', // Need empty placeholder to enable show/hide for clear button
|
|
944
|
+
},
|
|
945
|
+
}]
|
|
946
|
+
}] });
|
|
947
|
+
|
|
948
|
+
/**
|
|
949
|
+
* Search Component
|
|
950
|
+
*
|
|
951
|
+
* Use to contain the search input and buttons.
|
|
952
|
+
* Only `SearchInput` is required, while `SearchClear` and `SearchButton` are optional.
|
|
953
|
+
*
|
|
954
|
+
* @example
|
|
955
|
+
* <div ksd-search>
|
|
956
|
+
* <input ksd-search-input />
|
|
957
|
+
* <button ksd-search-clear></button>
|
|
958
|
+
* <button ksd-search-button></button>
|
|
959
|
+
* </div>
|
|
960
|
+
*/
|
|
961
|
+
class Search {
|
|
962
|
+
input = contentChild(SearchInput, ...(ngDevMode ? [{ debugName: "input" }] : []));
|
|
963
|
+
constructor() {
|
|
964
|
+
afterNextRender(() => {
|
|
965
|
+
if (!this.input()) {
|
|
966
|
+
logIfDevMode({
|
|
967
|
+
component: 'Search',
|
|
968
|
+
message: 'Missing required elements: ksd-search-input must be provided as child. Check imports and markup.',
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Search, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
974
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.9", type: Search, isStandalone: true, selector: "ksd-search", host: { classAttribute: "ds-search" }, queries: [{ propertyName: "input", first: true, predicate: SearchInput, descendants: true, isSignal: true }], hostDirectives: [{ directive: CommonInputs, inputs: ["data-size", "data-size", "data-color", "data-color"] }], ngImport: i0, template: `
|
|
975
|
+
<ng-content select="[ksd-search-input]" />
|
|
976
|
+
<ng-content select="[ksd-search-clear]" />
|
|
977
|
+
<ng-content select="[ksd-search-button]" />
|
|
978
|
+
`, isInline: true });
|
|
979
|
+
}
|
|
980
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: Search, decorators: [{
|
|
981
|
+
type: Component,
|
|
982
|
+
args: [{
|
|
983
|
+
selector: 'ksd-search',
|
|
984
|
+
template: `
|
|
985
|
+
<ng-content select="[ksd-search-input]" />
|
|
986
|
+
<ng-content select="[ksd-search-clear]" />
|
|
987
|
+
<ng-content select="[ksd-search-button]" />
|
|
988
|
+
`,
|
|
989
|
+
host: {
|
|
990
|
+
class: 'ds-search',
|
|
991
|
+
},
|
|
992
|
+
hostDirectives: [
|
|
993
|
+
{
|
|
994
|
+
directive: CommonInputs,
|
|
995
|
+
inputs: ['data-size', 'data-color'],
|
|
996
|
+
},
|
|
997
|
+
],
|
|
998
|
+
}]
|
|
999
|
+
}], ctorParameters: () => [], propDecorators: { input: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SearchInput), { isSignal: true }] }] } });
|
|
1000
|
+
|
|
1001
|
+
/**
|
|
1002
|
+
* Search button
|
|
1003
|
+
*
|
|
1004
|
+
* Used within Search to provide a submit button.
|
|
1005
|
+
*
|
|
1006
|
+
* @param {('primary' | 'secondary')} [variant] - Specify which button variant to use
|
|
1007
|
+
* @param {string} [aria-label] - Aria label for the button
|
|
1008
|
+
*
|
|
1009
|
+
*/
|
|
1010
|
+
class SearchButton {
|
|
1011
|
+
/**
|
|
1012
|
+
* Specify which button variant to use
|
|
1013
|
+
*
|
|
1014
|
+
* @default 'primary'
|
|
1015
|
+
*/
|
|
1016
|
+
variant = input('primary', ...(ngDevMode ? [{ debugName: "variant" }] : []));
|
|
1017
|
+
/**
|
|
1018
|
+
* Aria label for the button
|
|
1019
|
+
*/
|
|
1020
|
+
ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel", alias: 'aria-label' }] : [{ alias: 'aria-label' }]));
|
|
1021
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: SearchButton, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1022
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.9", type: SearchButton, isStandalone: true, selector: "button[ksd-search-button]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "submit" }, properties: { "attr.aria-label": "this.ariaLabel()", "attr.data-variant": "this.variant()" }, classAttribute: "ds-button" }, ngImport: i0 });
|
|
1023
|
+
}
|
|
1024
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: SearchButton, decorators: [{
|
|
1025
|
+
type: Directive,
|
|
1026
|
+
args: [{
|
|
1027
|
+
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
1028
|
+
selector: 'button[ksd-search-button]',
|
|
1029
|
+
standalone: true,
|
|
1030
|
+
host: {
|
|
1031
|
+
class: 'ds-button',
|
|
1032
|
+
type: 'submit',
|
|
1033
|
+
'[attr.aria-label]': 'this.ariaLabel()',
|
|
1034
|
+
'[attr.data-variant]': 'this.variant()',
|
|
1035
|
+
},
|
|
1036
|
+
}]
|
|
1037
|
+
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }] } });
|
|
1038
|
+
|
|
1039
|
+
/**
|
|
1040
|
+
* Search clear button
|
|
1041
|
+
*
|
|
1042
|
+
* Used within Search to provide a clear button.
|
|
1043
|
+
*
|
|
1044
|
+
* @param {string} [aria-label] - Aria label for the button.
|
|
1045
|
+
*
|
|
1046
|
+
* @event clearInput - Emitted when the clear button is clicked.
|
|
1047
|
+
* Use this to notify controlled forms that the input should be cleared.
|
|
1048
|
+
*
|
|
1049
|
+
*/
|
|
1050
|
+
class SearchClear {
|
|
1051
|
+
/**
|
|
1052
|
+
* Aria label for the button
|
|
1053
|
+
* @default 'Tøm'
|
|
1054
|
+
*/
|
|
1055
|
+
ariaLabel = input('Tøm', ...(ngDevMode ? [{ debugName: "ariaLabel", alias: 'aria-label' }] : [{ alias: 'aria-label' }]));
|
|
1056
|
+
/**
|
|
1057
|
+
* Output to notify controlled forms that input should be cleared
|
|
1058
|
+
*/
|
|
1059
|
+
clearInput = output();
|
|
1060
|
+
handleClear(e) {
|
|
1061
|
+
const target = e.target;
|
|
1062
|
+
let inputElement = null;
|
|
1063
|
+
if (target instanceof HTMLElement) {
|
|
1064
|
+
inputElement = target.closest('.ds-search')?.querySelector('input');
|
|
1065
|
+
}
|
|
1066
|
+
if (!inputElement)
|
|
1067
|
+
throw new Error('Input is missing');
|
|
1068
|
+
if (!(inputElement instanceof HTMLInputElement)) {
|
|
1069
|
+
throw new Error('Input is not an input element');
|
|
1070
|
+
}
|
|
1071
|
+
e.preventDefault();
|
|
1072
|
+
inputElement.value = '';
|
|
1073
|
+
this.clearInput.emit();
|
|
1074
|
+
inputElement.focus();
|
|
1075
|
+
}
|
|
1076
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: SearchClear, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1077
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.9", type: SearchClear, isStandalone: true, selector: "button[ksd-search-clear]", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clearInput: "clearInput" }, host: { attributes: { "type": "reset" }, listeners: { "click": "handleClear($event)" }, properties: { "attr.data-variant": "'tertiary'", "attr.aria-label": "this.ariaLabel()" }, classAttribute: "ds-button" }, ngImport: i0 });
|
|
1078
|
+
}
|
|
1079
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: SearchClear, decorators: [{
|
|
1080
|
+
type: Directive,
|
|
1081
|
+
args: [{
|
|
1082
|
+
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
1083
|
+
selector: 'button[ksd-search-clear]',
|
|
1084
|
+
standalone: true,
|
|
1085
|
+
host: {
|
|
1086
|
+
class: 'ds-button',
|
|
1087
|
+
type: 'reset',
|
|
1088
|
+
'[attr.data-variant]': "'tertiary'",
|
|
1089
|
+
'[attr.aria-label]': 'this.ariaLabel()',
|
|
1090
|
+
'(click)': 'handleClear($event)',
|
|
1091
|
+
},
|
|
1092
|
+
}]
|
|
1093
|
+
}], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], clearInput: [{ type: i0.Output, args: ["clearInput"] }] } });
|
|
1094
|
+
|
|
1095
|
+
/**
|
|
1096
|
+
* Generated bundle index. Do not edit.
|
|
1097
|
+
*/
|
|
1098
|
+
|
|
1099
|
+
export { Alert, Button, Card, CardBlock, CommonInputs, Details, DetailsContent, DetailsSummary, Field, FieldDescription, FieldError, Fieldset, FieldsetDescription, FieldsetLegend, Input, Label, Paragraph, Popover, Search, SearchButton, SearchClear, SearchInput, Spinner, ValidationMessage };
|
|
1100
|
+
//# sourceMappingURL=ks-digital-designsystem-angular.mjs.map
|