@thalassic/themes 0.3.0 → 0.4.0

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 (28) hide show
  1. package/package.json +1 -1
  2. package/themes/thalassic/_colors.scss +1 -1
  3. package/themes/thalassic/components/_checkbox.scss +95 -0
  4. package/themes/thalassic/components/_divider.scss +91 -0
  5. package/themes/thalassic/components/_icon.scss +15 -0
  6. package/themes/thalassic/components/_radio-button.scss +103 -0
  7. package/themes/thalassic/components/alert/_alert-color.scss +43 -0
  8. package/themes/thalassic/components/alert/_alert.scss +25 -0
  9. package/themes/thalassic/components/alert/_index.scss +2 -0
  10. package/themes/thalassic/components/button/_button-color.scss +41 -0
  11. package/themes/thalassic/components/button/_button-size.scss +52 -0
  12. package/themes/thalassic/components/button/_button-variant.scss +136 -0
  13. package/themes/thalassic/components/button/_button.scss +53 -0
  14. package/themes/thalassic/components/button/_index.scss +4 -0
  15. package/themes/thalassic/components/form/_form-control-addon.scss +8 -0
  16. package/themes/thalassic/components/form/_form-control-group-size.scss +46 -0
  17. package/themes/thalassic/components/form/_form-control-group.scss +58 -0
  18. package/themes/thalassic/components/form/_form-control-size.scss +46 -0
  19. package/themes/thalassic/components/form/_form-control.scss +45 -0
  20. package/themes/thalassic/components/form/_form-item.scss +79 -0
  21. package/themes/thalassic/components/form/_index.scss +6 -0
  22. package/themes/thalassic/components/index.scss +9 -0
  23. package/themes/thalassic/components/switch/_index.scss +2 -0
  24. package/themes/thalassic/components/switch/_switch-color.scss +36 -0
  25. package/themes/thalassic/components/switch/_switch.scss +85 -0
  26. package/themes/thalassic/index.scss +3 -0
  27. package/themes/thalassic/mixins/_index.scss +1 -0
  28. package/themes/thalassic/mixins/focus-ring.scss +4 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thalassic/themes",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "license": "MIT",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
@@ -25,7 +25,7 @@
25
25
  // Success
26
26
  --color-success: #{map.get(common-palettes.$green, 40)};
27
27
  --color-on-success: #{map.get(common-palettes.$green, 100)};
28
- --color-success-container: #{map.get(common-palettes.$green, 90)};
28
+ --color-success-container: #{map.get(common-palettes.$green, 95)};
29
29
  --color-on-success-container: #{map.get(common-palettes.$green, 30)};
30
30
 
31
31
  // Danger
@@ -0,0 +1,95 @@
1
+ @use '../mixins/index' as mixins;
2
+
3
+ .tls-checkbox {
4
+ --tls-checkbox-size: 20px;
5
+ --tls-checkbox-border-width: 1px;
6
+ --tls-checkbox-border-color: var(--color-primary);
7
+ --tls-checkbox-checked-icon-color: var(--color-surface);
8
+
9
+ position: relative;
10
+
11
+ width: var(--tls-checkbox-size);
12
+ height: var(--tls-checkbox-size);
13
+
14
+ display: inline-block;
15
+
16
+ transition: filter var(--motion-fast) var(--motion-ease-in-out);
17
+
18
+ .tls-checkbox-input {
19
+ width: 100%;
20
+ height: 100%;
21
+ margin: 0;
22
+
23
+ appearance: none;
24
+
25
+ border: var(--tls-checkbox-border-width) solid var(--tls-checkbox-border-color);
26
+ border-radius: 4px;
27
+
28
+ cursor: pointer;
29
+
30
+ background-color: var(--color-surface);
31
+
32
+ transition:
33
+ box-shadow var(--motion-fast) var(--motion-ease-in-out),
34
+ border-color var(--motion-fast) var(--motion-ease-in-out),
35
+ background-color var(--motion-fast) var(--motion-ease-in-out);
36
+
37
+ &:checked {
38
+ background-color: var(--color-primary);
39
+ }
40
+
41
+ &:focus-visible {
42
+ @include mixins.focus-ring;
43
+ }
44
+ }
45
+
46
+ .tls-checkbox-icon {
47
+ position: absolute;
48
+ inset: 0;
49
+
50
+ opacity: 0;
51
+ scale: 0;
52
+
53
+ pointer-events: none;
54
+
55
+ color: var(--tls-checkbox-checked-icon-color);
56
+
57
+ transition:
58
+ scale var(--motion-default) var(--motion-ease-bounce),
59
+ opacity var(--motion-fast) var(--motion-ease-in-out);
60
+ }
61
+
62
+ // Checked & Indeterminate
63
+ &.tls-checkbox--checked,
64
+ &.tls-checkbox--indeterminate {
65
+ .tls-checkbox-input {
66
+ background-color: var(--color-primary);
67
+ }
68
+
69
+ .tls-checkbox-icon {
70
+ opacity: 1;
71
+ scale: 1;
72
+ }
73
+ }
74
+
75
+ // Form control
76
+ &.tls-checkbox--disabled {
77
+ --tls-checkbox-border-color: var(--color-outline);
78
+
79
+ filter: brightness(0.9);
80
+
81
+ cursor: not-allowed;
82
+
83
+ .tls-checkbox-input {
84
+ pointer-events: none;
85
+ }
86
+ }
87
+
88
+ &:not(.tls-checkbox--disabled).tls-checkbox--touched.tls-checkbox--invalid {
89
+ --tls-checkbox-border-color: var(--color-danger);
90
+
91
+ .tls-checkbox-input {
92
+ box-shadow: 0 0 4px -1px var(--color-danger);
93
+ }
94
+ }
95
+ }
@@ -0,0 +1,91 @@
1
+ .tls-divider {
2
+ --tls-divider-line-color: var(--color-outline-variant);
3
+ --tls-divider-line-size: 1px;
4
+ --tls-divider-content-gap: var(--spacing-3);
5
+ --tls-divider-inset: 5%;
6
+
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ gap: var(--tls-divider-content-gap);
11
+
12
+ .tls-divider-content {
13
+ min-width: fit-content;
14
+ }
15
+
16
+ &:has(.tls-divider-content:empty) {
17
+ .tls-divider-content {
18
+ display: none;
19
+ }
20
+
21
+ .tls-divider-line.tls-divider-line--start {
22
+ display: none;
23
+ }
24
+ }
25
+
26
+ // Orientation
27
+ &.tls-divider--horizontal {
28
+ .tls-divider-line {
29
+ border-right-width: 0;
30
+ border-bottom-width: var(--tls-divider-line-size);
31
+ }
32
+ }
33
+
34
+ &.tls-divider--vertical {
35
+ flex-direction: column;
36
+
37
+ .tls-divider-line {
38
+ border-right-width: var(--tls-divider-line-size);
39
+ border-bottom-width: 0;
40
+ }
41
+ }
42
+
43
+ // Position
44
+ &.tls-divider--start {
45
+ .tls-divider-line.tls-divider-line--start {
46
+ flex-basis: var(--tls-divider-inset);
47
+ }
48
+
49
+ &.tls-divider--flush {
50
+ .tls-divider-line.tls-divider-line--start {
51
+ display: none;
52
+ }
53
+ }
54
+ }
55
+
56
+ &.tls-divider--end {
57
+ .tls-divider-line.tls-divider-line--end {
58
+ flex-basis: var(--tls-divider-inset);
59
+ }
60
+
61
+ &.tls-divider--flush {
62
+ .tls-divider-line.tls-divider-line--end {
63
+ display: none;
64
+ }
65
+ }
66
+ }
67
+
68
+ // Variant
69
+ &.tls-divider--dashed {
70
+ --tls-divider-line-variant: dashed;
71
+ }
72
+
73
+ &.tls-divider--dotted {
74
+ --tls-divider-line-variant: dotted;
75
+ }
76
+
77
+ &.tls-divider--solid {
78
+ --tls-divider-line-variant: solid;
79
+ }
80
+
81
+ // Divider line
82
+ .tls-divider-line {
83
+ flex-basis: 100%;
84
+ flex-grow: 1;
85
+
86
+ border-top-width: 0;
87
+ border-left-width: 0;
88
+ border-style: var(--tls-divider-line-variant);
89
+ border-color: var(--tls-divider-line-color);
90
+ }
91
+ }
@@ -0,0 +1,15 @@
1
+ .tls-icon {
2
+ width: auto;
3
+ height: auto;
4
+
5
+ min-width: auto;
6
+ min-height: auto;
7
+
8
+ display: inline-block;
9
+
10
+ color: inherit;
11
+
12
+ .tls-svg-icon {
13
+ color: inherit;
14
+ }
15
+ }
@@ -0,0 +1,103 @@
1
+ @use '../mixins/index' as mixins;
2
+
3
+ .tls-radio-button {
4
+ --tls-radio-button-size: 20px;
5
+ --tls-radio-button-circle-size: 12px;
6
+ --tls-radio-button-border-size: 1px;
7
+ --tls-radio-button-border-color: var(--color-primary);
8
+ --tls-radio-button-circle-color: var(--color-primary);
9
+
10
+ position: relative;
11
+
12
+ width: var(--tls-radio-button-size);
13
+ height: var(--tls-radio-button-size);
14
+
15
+ display: inline-block;
16
+
17
+ transition: filter var(--motion-fast) var(--motion-ease-in-out);
18
+
19
+ .tls-radio-button-input {
20
+ width: 100%;
21
+ height: 100%;
22
+ margin: 0;
23
+
24
+ appearance: none;
25
+
26
+ border: var(--tls-radio-button-border-size) solid var(--tls-radio-button-border-color);
27
+ border-radius: 50%;
28
+
29
+ cursor: pointer;
30
+
31
+ background-color: var(--color-surface);
32
+
33
+ transition:
34
+ box-shadow var(--motion-fast) var(--motion-ease-in-out),
35
+ border-color var(--motion-fast) var(--motion-ease-in-out),
36
+ background-color var(--motion-fast) var(--motion-ease-in-out);
37
+
38
+ &:focus-visible {
39
+ @include mixins.focus-ring;
40
+ }
41
+ }
42
+
43
+ .tls-radio-button-circle {
44
+ position: absolute;
45
+ inset: 0;
46
+
47
+ display: flex;
48
+ justify-content: center;
49
+ align-items: center;
50
+
51
+ pointer-events: none;
52
+
53
+ &::before {
54
+ content: '';
55
+
56
+ width: var(--tls-radio-button-circle-size);
57
+ height: var(--tls-radio-button-circle-size);
58
+
59
+ display: inline-block;
60
+
61
+ opacity: 0;
62
+ scale: 0.75;
63
+
64
+ border-radius: 50%;
65
+ background-color: var(--tls-radio-button-circle-color);
66
+
67
+ transition:
68
+ scale var(--motion-fast) var(--motion-ease-in-out),
69
+ opacity var(--motion-default) var(--motion-ease-in-out);
70
+ }
71
+ }
72
+
73
+ // Checked
74
+ &.tls-radio-button--checked {
75
+ .tls-radio-button-circle {
76
+ &::before {
77
+ opacity: 1;
78
+ scale: 1;
79
+ }
80
+ }
81
+ }
82
+
83
+ // Form control
84
+ &.tls-radio-button--disabled {
85
+ --tls-radio-button-border-color: var(--color-outline);
86
+
87
+ filter: brightness(0.9);
88
+
89
+ cursor: not-allowed;
90
+
91
+ .tls-radio-button-input {
92
+ pointer-events: none;
93
+ }
94
+ }
95
+
96
+ &:not(.tls-radio-button--disabled).tls-radio-button--touched.tls-radio-button--invalid {
97
+ --tls-radio-button-border-color: var(--color-danger);
98
+
99
+ .tls-radio-button-input {
100
+ box-shadow: 0 0 4px -1px var(--color-danger);
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,43 @@
1
+ .tls-alert {
2
+ &.tls-alert--primary {
3
+ --tls-alert-border-color: var(--color-primary);
4
+ --tls-alert-color: var(--color-on-primary-container);
5
+ --tls-alert-background-color: var(--color-primary-container);
6
+ }
7
+
8
+ &.tls-alert--secondary {
9
+ --tls-alert-border-color: var(--color-secondary);
10
+ --tls-alert-color: var(--color-on-secondary-container);
11
+ --tls-alert-background-color: var(--color-secondary-container);
12
+ }
13
+
14
+ &.tls-alert--tertiary {
15
+ --tls-alert-border-color: var(--color-tertiary);
16
+ --tls-alert-color: var(--color-on-tertiary-container);
17
+ --tls-alert-background-color: var(--color-tertiary-container);
18
+ }
19
+
20
+ &.tls-alert--success {
21
+ --tls-alert-border-color: var(--color-success);
22
+ --tls-alert-color: var(--color-on-success-container);
23
+ --tls-alert-background-color: var(--color-success-container);
24
+ }
25
+
26
+ &.tls-alert--info {
27
+ --tls-alert-border-color: var(--color-info);
28
+ --tls-alert-color: var(--color-on-info-container);
29
+ --tls-alert-background-color: var(--color-info-container);
30
+ }
31
+
32
+ &.tls-alert--warning {
33
+ --tls-alert-border-color: var(--color-warning);
34
+ --tls-alert-color: var(--color-on-warning-container);
35
+ --tls-alert-background-color: var(--color-warning-container);
36
+ }
37
+
38
+ &.tls-alert--danger {
39
+ --tls-alert-border-color: var(--color-danger);
40
+ --tls-alert-color: var(--color-on-danger-container);
41
+ --tls-alert-background-color: var(--color-danger-container);
42
+ }
43
+ }
@@ -0,0 +1,25 @@
1
+ .tls-alert {
2
+ --tls-alert-padding: var(--spacing-4);
3
+ --tls-alert-border-width: 1px;
4
+ --tls-alert-border-radius: var(--radius-sm);
5
+ --tls-alert-label-font-weight: var(--font-weight-bold);
6
+
7
+ padding: var(--tls-alert-padding);
8
+
9
+ display: flex;
10
+
11
+ border-radius: var(--tls-alert-border-radius);
12
+ border: var(--tls-alert-border-width) solid var(--tls-alert-border-color);
13
+
14
+ color: var(--tls-alert-color);
15
+ background-color: var(--tls-alert-background-color);
16
+
17
+ &-body {
18
+ &__label {
19
+ font-weight: var(--tls-alert-label-font-weight);
20
+ }
21
+
22
+ &__content {
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,2 @@
1
+ @forward 'alert';
2
+ @forward 'alert-color';
@@ -0,0 +1,41 @@
1
+ .tls-button {
2
+ &.tls-button--primary {
3
+ --tls-button-on-color: var(--color-on-primary);
4
+ --tls-button-color: var(--color-primary);
5
+ }
6
+
7
+ &.tls-button--secondary {
8
+ --tls-button-on-color: var(--color-on-secondary);
9
+ --tls-button-color: var(--color-secondary);
10
+ }
11
+
12
+ &.tls-button--tertiary {
13
+ --tls-button-on-color: var(--color-on-tertiary);
14
+ --tls-button-color: var(--color-tertiary);
15
+ }
16
+
17
+ &.tls-button--success {
18
+ --tls-button-on-color: var(--color-on-success);
19
+ --tls-button-color: var(--color-success);
20
+ }
21
+
22
+ &.tls-button--info {
23
+ --tls-button-on-color: var(--color-on-info);
24
+ --tls-button-color: var(--color-info);
25
+ }
26
+
27
+ &.tls-button--warning {
28
+ --tls-button-on-color: var(--color-on-warning);
29
+ --tls-button-color: var(--color-warning);
30
+ }
31
+
32
+ &.tls-button--danger {
33
+ --tls-button-on-color: var(--color-on-danger);
34
+ --tls-button-color: var(--color-danger);
35
+ }
36
+
37
+ &.tls-button--disabled {
38
+ --tls-button-on-color: var(--color-on-surface-variant);
39
+ --tls-button-color: var(--color-surface-variant);
40
+ }
41
+ }
@@ -0,0 +1,52 @@
1
+ .tls-button {
2
+ --tls-button-width: auto;
3
+
4
+ width: var(--tls-button-width);
5
+ height: var(--tls-button-height);
6
+ padding-inline: var(--tls-button-padding-inline);
7
+
8
+ font-size: var(--tls-button-font-size);
9
+ font-weight: var(--tls-button-font-weight);
10
+ line-height: var(--tls-button-line-height);
11
+ letter-spacing: var(--tls-button-letter-spacing);
12
+
13
+ &.tls-button--icon-only {
14
+ padding-inline: 0;
15
+
16
+ aspect-ratio: 1/1;
17
+ }
18
+
19
+ &.tls-button--fluid {
20
+ --tls-button-width: 100%;
21
+ }
22
+
23
+ &.tls-button--sm {
24
+ --tls-button-height: var(--control-height-sm);
25
+ --tls-button-padding-inline: var(--spacing-3);
26
+
27
+ --tls-button-font-size: var(--font-label-small-size);
28
+ --tls-button-font-weight: var(--font-label-small-weight);
29
+ --tls-button-line-height: var(--font-label-small-line-height);
30
+ --tls-button-letter-spacing: var(--font-label-small-letter-spacing);
31
+ }
32
+
33
+ &.tls-button--md {
34
+ --tls-button-height: var(--control-height-md);
35
+ --tls-button-padding-inline: var(--spacing-4);
36
+
37
+ --tls-button-font-size: var(--font-label-medium-size);
38
+ --tls-button-font-weight: var(--font-label-medium-weight);
39
+ --tls-button-line-height: var(--font-label-medium-line-height);
40
+ --tls-button-letter-spacing: var(--font-label-medium-letter-spacing);
41
+ }
42
+
43
+ &.tls-button--lg {
44
+ --tls-button-height: var(--control-height-lg);
45
+ --tls-button-padding-inline: var(--spacing-5);
46
+
47
+ --tls-button-font-size: var(--font-label-large-size);
48
+ --tls-button-font-weight: var(--font-label-large-weight);
49
+ --tls-button-line-height: var(--font-label-large-line-height);
50
+ --tls-button-letter-spacing: var(--font-label-large-letter-spacing);
51
+ }
52
+ }
@@ -0,0 +1,136 @@
1
+ .tls-button {
2
+ @mixin hover-focus-state {
3
+ &:not(.tls-button--disabled):hover,
4
+ &:not(.tls-button--disabled):focus-visible {
5
+ @content;
6
+ }
7
+ }
8
+
9
+ @mixin active-state {
10
+ &:not(.tls-button--disabled):active {
11
+ @content;
12
+ }
13
+ }
14
+
15
+ // Variants
16
+ &--filled {
17
+ color: var(--tls-button-on-color);
18
+
19
+ &::before {
20
+ background-color: var(--tls-button-color);
21
+ }
22
+
23
+ @include hover-focus-state {
24
+ &::before {
25
+ opacity: 0.85;
26
+ }
27
+ }
28
+
29
+ @include active-state {
30
+ &::before {
31
+ opacity: 0.75;
32
+ }
33
+ }
34
+ }
35
+
36
+ &--outlined {
37
+ color: var(--tls-button-color);
38
+
39
+ &::before {
40
+ background-color: var(--tls-button-color);
41
+
42
+ opacity: 0;
43
+ }
44
+
45
+ &::after {
46
+ border: var(--tls-button-border-width) solid var(--tls-button-color);
47
+
48
+ transition: border-color var(--motion-fast) var(--motion-ease-in-out);
49
+ }
50
+
51
+ @include hover-focus-state {
52
+ &::before {
53
+ opacity: 0.075;
54
+ }
55
+ }
56
+
57
+ @include active-state {
58
+ &::before {
59
+ opacity: 0.15;
60
+ }
61
+ }
62
+ }
63
+
64
+ &--text {
65
+ color: var(--tls-button-color);
66
+
67
+ &::before {
68
+ background-color: var(--tls-button-color);
69
+
70
+ opacity: 0;
71
+ }
72
+
73
+ @include hover-focus-state {
74
+ &::before {
75
+ opacity: 0.075;
76
+ }
77
+ }
78
+
79
+ @include active-state {
80
+ &::before {
81
+ opacity: 0.15;
82
+ }
83
+ }
84
+ }
85
+
86
+ &--elevated {
87
+ color: var(--tls-button-color);
88
+
89
+ transition: box-shadow var(--motion-fast) var(--motion-ease-in-out);
90
+
91
+ &::before {
92
+ background-color: var(--tls-button-color);
93
+
94
+ opacity: 0;
95
+ }
96
+
97
+ &::after {
98
+ box-shadow: var(--shadow-sm);
99
+ }
100
+
101
+ @include hover-focus-state {
102
+ &::before {
103
+ opacity: 0.075;
104
+ }
105
+ }
106
+
107
+ @include active-state {
108
+ &::before {
109
+ opacity: 0.15;
110
+ }
111
+
112
+ &::after {
113
+ box-shadow: var(--shadow-xs);
114
+ }
115
+ }
116
+ }
117
+
118
+ &--disabled {
119
+ color: var(--tls-button-on-color);
120
+
121
+ cursor: not-allowed;
122
+
123
+ &::before {
124
+ opacity: 1;
125
+
126
+ transition: none;
127
+ }
128
+
129
+ &::after {
130
+ border: var(--tls-button-border-width) solid var(--color-outline);
131
+ box-shadow: none;
132
+
133
+ transition: none;
134
+ }
135
+ }
136
+ }
@@ -0,0 +1,53 @@
1
+ @use '../../mixins' as mixins;
2
+
3
+ .tls-button {
4
+ --tls-button-border-width: 1px;
5
+
6
+ position: relative;
7
+ z-index: 1;
8
+
9
+ display: inline-flex;
10
+ justify-content: center;
11
+ align-items: center;
12
+ gap: 0.25rem;
13
+
14
+ cursor: pointer;
15
+ user-select: none;
16
+
17
+ border-radius: var(--radius-md);
18
+ background-color: var(--color-surface);
19
+
20
+ transition: color var(--motion-fast) var(--motion-ease-in-out);
21
+
22
+ &:focus-visible {
23
+ @include mixins.focus-ring;
24
+ }
25
+
26
+ &::before,
27
+ &::after {
28
+ content: '';
29
+ width: 100%;
30
+ height: 100%;
31
+
32
+ position: absolute;
33
+ z-index: -1;
34
+
35
+ border: var(--tls-button-border-width) solid var(--tls-button-color);
36
+ border-radius: var(--radius-md);
37
+ }
38
+
39
+ &::before {
40
+ transition:
41
+ background-color var(--motion-fast) var(--motion-ease-in-out),
42
+ opacity var(--motion-fast) var(--motion-ease-in-out);
43
+ }
44
+
45
+ &::after {
46
+ border: none;
47
+ border-radius: var(--radius-md);
48
+
49
+ transition:
50
+ border-color var(--motion-fast) var(--motion-ease-in-out),
51
+ box-shadow var(--motion-fast) var(--motion-ease-in-out);
52
+ }
53
+ }
@@ -0,0 +1,4 @@
1
+ @forward 'button';
2
+ @forward 'button-variant';
3
+ @forward 'button-color';
4
+ @forward 'button-size';
@@ -0,0 +1,8 @@
1
+ @use '../../mixins' as mixins;
2
+
3
+ .tls-form-control-addon {
4
+ &:focus-visible {
5
+ @include mixins.focus-ring;
6
+ border-radius: var(--radius-md);
7
+ }
8
+ }
@@ -0,0 +1,46 @@
1
+ .tls-form-control-group {
2
+ --tls-form-control-group-width: auto;
3
+
4
+ width: var(--tls-form-control-group-width);
5
+ height: var(--tls-form-control-group-height);
6
+ padding-inline: var(--tls-form-control-group-padding-inline);
7
+
8
+ font-size: var(--tls-form-control-group-font-size);
9
+ font-weight: var(--tls-form-control-group-font-weight);
10
+ line-height: var(--tls-form-control-group-line-height);
11
+ letter-spacing: var(--tls-form-control-group-letter-spacing);
12
+
13
+ &.tls-form-control-group--fluid {
14
+ --tls-form-control-group-width: 100%;
15
+ }
16
+
17
+ &.tls-form-control-group--sm {
18
+ --tls-form-control-group-height: var(--control-height-sm);
19
+ --tls-form-control-group-padding-inline: var(--spacing-2);
20
+
21
+ --tls-form-control-group-font-size: var(--font-label-small-size);
22
+ --tls-form-control-group-font-weight: var(--font-label-small-weight);
23
+ --tls-form-control-group-line-height: var(--font-label-small-line-height);
24
+ --tls-form-control-group-letter-spacing: var(--font-label-small-letter-spacing);
25
+ }
26
+
27
+ &.tls-form-control-group--md {
28
+ --tls-form-control-group-height: var(--control-height-md);
29
+ --tls-form-control-group-padding-inline: var(--spacing-2);
30
+
31
+ --tls-form-control-group-font-size: var(--font-label-medium-size);
32
+ --tls-form-control-group-font-weight: var(--font-label-medium-weight);
33
+ --tls-form-control-group-line-height: var(--font-label-medium-line-height);
34
+ --tls-form-control-group-letter-spacing: var(--font-label-medium-letter-spacing);
35
+ }
36
+
37
+ &.tls-form-control-group--lg {
38
+ --tls-form-control-group-height: var(--control-height-lg);
39
+ --tls-form-control-group-padding-inline: var(--spacing-3);
40
+
41
+ --tls-form-control-group-font-size: var(--font-label-large-size);
42
+ --tls-form-control-group-font-weight: var(--font-label-large-weight);
43
+ --tls-form-control-group-line-height: var(--font-label-large-line-height);
44
+ --tls-form-control-group-letter-spacing: var(--font-label-large-letter-spacing);
45
+ }
46
+ }
@@ -0,0 +1,58 @@
1
+ .tls-form-control-group {
2
+ --tls-form-control-group-border-width: 1px;
3
+ --tls-form-control-group-border-style: solid;
4
+ --tls-form-control-group-border-color: var(--color-outline);
5
+
6
+ border-radius: var(--radius-md);
7
+ border: var(--tls-form-control-group-border-width) var(--tls-form-control-group-border-style)
8
+ var(--tls-form-control-group-border-color);
9
+
10
+ transition:
11
+ border-color var(--motion-fast) var(--motion-ease-in-out),
12
+ background-color var(--motion-fast) var(--motion-ease-in-out),
13
+ box-shadow var(--motion-fast) var(--motion-ease-in-out);
14
+
15
+ &:hover {
16
+ --tls-form-control-group-border-color: var(--color-primary);
17
+ }
18
+
19
+ &:has(input.tls-form-control:focus) {
20
+ border: 1px solid var(--color-primary);
21
+ box-shadow: 0 0 3px -1px var(--color-primary);
22
+ }
23
+
24
+ .tls-form-control {
25
+ flex-grow: 1;
26
+ padding: 0;
27
+
28
+ border: none;
29
+ box-shadow: none;
30
+ background: transparent;
31
+ }
32
+
33
+ // Form control
34
+ &.tls-form-control.tls-form-control--disabled,
35
+ &:has(.tls-form-control.tls-form-control.tls-form-control--disabled) {
36
+ --tls-form-control-group-border-color: var(--color-outline);
37
+ background-color: var(--color-surface-variant);
38
+
39
+ cursor: not-allowed;
40
+ }
41
+
42
+ &:not(
43
+ .tls-form-control--disabled
44
+ ).tls-form-control.tls-form-control--touched.tls-form-control--invalid,
45
+ &:has(
46
+ .tls-form-control:not(
47
+ .tls-form-control--disabled
48
+ ).tls-form-control.tls-form-control--touched.tls-form-control--invalid
49
+ ) {
50
+ --tls-form-control-group-border-color: var(--color-danger);
51
+
52
+ color: var(--color-danger);
53
+
54
+ .tls-form-control::placeholder {
55
+ color: var(--color-danger);
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,46 @@
1
+ .tls-form-control {
2
+ --tls-form-control-width: auto;
3
+
4
+ width: var(--tls-form-control-width);
5
+ height: var(--tls-form-control-height);
6
+ padding-inline: var(--tls-form-control-padding-inline);
7
+
8
+ font-size: var(--tls-form-control-font-size);
9
+ font-weight: var(--tls-form-control-font-weight);
10
+ line-height: var(--tls-form-control-line-height);
11
+ letter-spacing: var(--tls-form-control-letter-spacing);
12
+
13
+ &.tls-form-control--fluid {
14
+ --tls-form-control-width: 100%;
15
+ }
16
+
17
+ &.tls-form-control--sm {
18
+ --tls-form-control-height: var(--control-height-sm);
19
+ --tls-form-control-padding-inline: var(--spacing-2);
20
+
21
+ --tls-form-control-font-size: var(--font-label-small-size);
22
+ --tls-form-control-font-weight: var(--font-label-small-weight);
23
+ --tls-form-control-line-height: var(--font-label-small-line-height);
24
+ --tls-form-control-letter-spacing: var(--font-label-small-letter-spacing);
25
+ }
26
+
27
+ &.tls-form-control--md {
28
+ --tls-form-control-height: var(--control-height-md);
29
+ --tls-form-control-padding-inline: var(--spacing-2);
30
+
31
+ --tls-form-control-font-size: var(--font-label-medium-size);
32
+ --tls-form-control-font-weight: var(--font-label-medium-weight);
33
+ --tls-form-control-line-height: var(--font-label-medium-line-height);
34
+ --tls-form-control-letter-spacing: var(--font-label-medium-letter-spacing);
35
+ }
36
+
37
+ &.tls-form-control--lg {
38
+ --tls-form-control-height: var(--control-height-lg);
39
+ --tls-form-control-padding-inline: var(--spacing-3);
40
+
41
+ --tls-form-control-font-size: var(--font-label-large-size);
42
+ --tls-form-control-font-weight: var(--font-label-large-weight);
43
+ --tls-form-control-line-height: var(--font-label-large-line-height);
44
+ --tls-form-control-letter-spacing: var(--font-label-large-letter-spacing);
45
+ }
46
+ }
@@ -0,0 +1,45 @@
1
+ .tls-form-control {
2
+ --tls-form-control-border-width: 1px;
3
+ --tls-form-control-border-style: solid;
4
+ --tls-form-control-border-color: var(--color-outline);
5
+
6
+ color: var(--color-on-surface);
7
+ background-color: var(--color-surface);
8
+
9
+ border-radius: var(--radius-md);
10
+ border: var(--tls-form-control-border-width) var(--tls-form-control-border-style)
11
+ var(--tls-form-control-border-color);
12
+
13
+ transition:
14
+ border-color var(--motion-fast) var(--motion-ease-in-out),
15
+ background-color var(--motion-fast) var(--motion-ease-in-out),
16
+ box-shadow var(--motion-fast) var(--motion-ease-in-out);
17
+
18
+ &:not(.tls-form-control--disabled):hover {
19
+ --tls-form-control-border-color: var(--color-primary);
20
+ }
21
+
22
+ &:focus {
23
+ border: 1px solid var(--color-primary);
24
+ box-shadow: 0 0 3px -1px var(--color-primary);
25
+ }
26
+
27
+ // Form control
28
+ &.tls-form-control--disabled {
29
+ background-color: var(--color-surface-variant);
30
+
31
+ cursor: not-allowed;
32
+ }
33
+
34
+ &:not(
35
+ .tls-form-control--disabled
36
+ ).tls-form-control.tls-form-control--touched.tls-form-control--invalid {
37
+ --tls-form-control-border-color: var(--color-danger);
38
+
39
+ color: var(--color-danger);
40
+
41
+ &::placeholder {
42
+ color: var(--color-danger);
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,79 @@
1
+ .tls-form-item {
2
+ display: flex;
3
+ flex-direction: column;
4
+
5
+ &.tls-form-item--invalid {
6
+ .form-item-label {
7
+ color: var(--color-danger);
8
+ }
9
+ }
10
+
11
+ &.tls-form-item--required {
12
+ .form-item-label__required {
13
+ display: inline;
14
+ }
15
+ }
16
+
17
+ &:not(.tls-form-item--error-space-reserved) {
18
+ .form-item-error {
19
+ min-height: auto;
20
+
21
+ &:empty {
22
+ display: none;
23
+ }
24
+ }
25
+ }
26
+
27
+ .form-item-label {
28
+ margin-bottom: 0.25rem;
29
+
30
+ display: flex;
31
+ gap: 0.25rem;
32
+
33
+ font-size: var(--font-label-medium-size);
34
+ font-weight: var(--font-label-medium-weight);
35
+ line-height: var(--font-label-medium-line-height);
36
+ letter-spacing: var(--font-label-medium-letter-spacing);
37
+
38
+ &:has(.form-item-label__text:empty) {
39
+ display: none;
40
+ }
41
+
42
+ &__required {
43
+ display: none;
44
+ color: var(--color-danger);
45
+
46
+ font-size: var(--font-label-large-size);
47
+ font-weight: var(--font-label-large-weight);
48
+ letter-spacing: var(--font-label-large-letter-spacing);
49
+ }
50
+ }
51
+
52
+ .form-item-error {
53
+ min-height: var(--font-label-small-line-height);
54
+ margin-top: 0.125rem;
55
+
56
+ color: var(--color-danger);
57
+
58
+ font-size: var(--font-label-small-size);
59
+ font-weight: var(--font-label-small-weight);
60
+ line-height: var(--font-label-small-line-height);
61
+ letter-spacing: var(--font-label-small-letter-spacing);
62
+
63
+ &__text {
64
+ display: inline-block;
65
+
66
+ opacity: 1;
67
+ transform: translateY(0);
68
+
69
+ transition:
70
+ transform var(--motion-default) var(--motion-ease-in),
71
+ opacity var(--motion-default) var(--motion-ease-in);
72
+
73
+ @starting-style {
74
+ opacity: 0;
75
+ transform: translateY(-100%);
76
+ }
77
+ }
78
+ }
79
+ }
@@ -0,0 +1,6 @@
1
+ @forward 'form-control';
2
+ @forward 'form-control-addon';
3
+ @forward 'form-control-group';
4
+ @forward 'form-control-group-size';
5
+ @forward 'form-control-size';
6
+ @forward 'form-item';
@@ -0,0 +1,9 @@
1
+ @forward 'alert';
2
+ @forward 'button';
3
+ @forward 'form';
4
+ @forward 'switch';
5
+
6
+ @forward 'checkbox';
7
+ @forward 'divider';
8
+ @forward 'icon';
9
+ @forward 'radio-button';
@@ -0,0 +1,2 @@
1
+ @forward 'switch';
2
+ @forward 'switch-color';
@@ -0,0 +1,36 @@
1
+ .tls-switch {
2
+ &.tls-switch--checked.tls-switch--primary {
3
+ --tls-switch-track-color: var(--color-primary);
4
+ --tls-switch-handle-color: var(--color-on-primary);
5
+ }
6
+
7
+ &.tls-switch--checked.tls-switch--secondary {
8
+ --tls-switch-track-color: var(--color-secondary);
9
+ --tls-switch-handle-color: var(--color-on-secondary);
10
+ }
11
+
12
+ &.tls-switch--checked.tls-switch--tertiary {
13
+ --tls-switch-track-color: var(--color-tertiary);
14
+ --tls-switch-handle-color: var(--color-on-tertiary);
15
+ }
16
+
17
+ &.tls-switch--checked.tls-switch--success {
18
+ --tls-switch-track-color: var(--color-success);
19
+ --tls-switch-handle-color: var(--color-on-success);
20
+ }
21
+
22
+ &.tls-switch--checked.tls-switch--info {
23
+ --tls-switch-track-color: var(--color-info);
24
+ --tls-switch-handle-color: var(--color-on-info);
25
+ }
26
+
27
+ &.tls-switch--checked.tls-switch--warning {
28
+ --tls-switch-track-color: var(--color-warning);
29
+ --tls-switch-handle-color: var(--color-on-warning);
30
+ }
31
+
32
+ &.tls-switch--checked.tls-switch--danger {
33
+ --tls-switch-track-color: var(--color-danger);
34
+ --tls-switch-handle-color: var(--color-on-danger);
35
+ }
36
+ }
@@ -0,0 +1,85 @@
1
+ @use '../../mixins' as mixins;
2
+
3
+ .tls-switch {
4
+ --tls-switch-width: 48px;
5
+ --tls-switch-height: var(--control-height-sm);
6
+ --tls-switch-handle-gap: 4px;
7
+ --tls-switch-handle-size: calc(
8
+ var(--tls-switch-height) - (var(--tls-switch-handle-gap) * 2) -
9
+ (var(--tls-switch-border-width) * 2)
10
+ );
11
+
12
+ --tls-switch-border-width: 1px;
13
+ --tls-switch-border-radius: 24px;
14
+
15
+ --tls-switch-track-color: var(--color-surface-variant);
16
+ --tls-switch-handle-color: var(--color-surface);
17
+ --tls-switch-border-color: var(--tls-switch-track-color);
18
+
19
+ width: var(--tls-switch-width);
20
+ height: var(--tls-switch-height);
21
+
22
+ display: flex;
23
+
24
+ border: var(--tls-switch-border-width) solid var(--tls-switch-border-color);
25
+ border-radius: var(--tls-switch-border-radius);
26
+
27
+ background-color: var(--tls-switch-track-color);
28
+
29
+ cursor: pointer;
30
+
31
+ transition:
32
+ background-color var(--motion-fast) var(--motion-ease-in-out),
33
+ border-color var(--motion-fast) var(--motion-ease-in-out),
34
+ box-shadow var(--motion-fast) var(--motion-ease-in-out),
35
+ filter var(--motion-fast) var(--motion-ease-in-out);
36
+
37
+ &:focus-visible {
38
+ @include mixins.focus-ring;
39
+ }
40
+
41
+ .tls-switch-input {
42
+ display: none;
43
+ }
44
+
45
+ .tls-switch-handle {
46
+ width: var(--tls-switch-handle-size);
47
+ height: var(--tls-switch-handle-size);
48
+
49
+ margin: calc(var(--tls-switch-handle-gap));
50
+
51
+ border-radius: 50%;
52
+
53
+ background-color: var(--tls-switch-handle-color);
54
+
55
+ box-shadow: var(--shadow-xs);
56
+
57
+ transition: transform var(--motion-fast) var(--motion-ease-in-out);
58
+ }
59
+
60
+ // Checked
61
+ &.tls-switch--checked {
62
+ --tls-switch-handle-gap: 3px;
63
+
64
+ .tls-switch-handle {
65
+ $translate-x: calc(
66
+ var(--tls-switch-width) - var(--tls-switch-handle-size) -
67
+ (var(--tls-switch-handle-gap) * 2) - (var(--tls-switch-border-width) * 2)
68
+ );
69
+
70
+ transform: translateX(#{$translate-x});
71
+ }
72
+ }
73
+
74
+ // Form control
75
+ &.tls-switch--disabled {
76
+ cursor: not-allowed;
77
+ filter: brightness(0.9);
78
+ }
79
+
80
+ &:not(.tls-switch--disabled).tls-switch--touched.tls-switch--invalid {
81
+ --tls-switch-border-color: var(--color-danger);
82
+
83
+ box-shadow: 0 0 4px -1px var(--color-danger);
84
+ }
85
+ }
@@ -1,4 +1,7 @@
1
+ @forward 'components';
2
+ @forward 'mixins';
1
3
  @forward 'semantic';
4
+
2
5
  @forward 'border';
3
6
  @forward 'colors';
4
7
  @forward 'motion';
@@ -0,0 +1 @@
1
+ @forward 'focus-ring';
@@ -0,0 +1,4 @@
1
+ @mixin focus-ring {
2
+ outline: var(--control-focus-ring-width) solid var(--control-focus-ring-color);
3
+ outline-offset: var(--control-focus-ring-offset);
4
+ }