m3-svelte 4.5.6 → 4.6.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.
@@ -39,6 +39,7 @@
39
39
  border: none;
40
40
  border-radius: var(--m3-card-shape);
41
41
  background-color: rgb(var(--m3-scheme-surface));
42
+ --m3-util-background: var(--m3-scheme-surface);
42
43
  color: rgb(var(--m3-scheme-on-surface));
43
44
  }
44
45
 
@@ -60,10 +61,12 @@
60
61
 
61
62
  .elevated {
62
63
  background-color: rgb(var(--m3-scheme-surface-container-low));
64
+ --m3-util-background: var(--m3-scheme-surface-container-low);
63
65
  box-shadow: var(--m3-util-elevation-1);
64
66
  }
65
67
  .filled {
66
68
  background-color: rgb(var(--m3-scheme-surface-container-highest));
69
+ --m3-util-background: var(--m3-scheme-surface-container-highest);
67
70
  }
68
71
  .outlined {
69
72
  border: solid 1px rgb(var(--m3-scheme-outline-variant));
@@ -77,6 +77,7 @@
77
77
  display: flex;
78
78
  flex-direction: column;
79
79
  background-color: rgb(var(--m3-scheme-surface-container-high));
80
+ --m3-util-background: var(--m3-scheme-surface-container-high);
80
81
  border: none;
81
82
  border-radius: var(--m3-dialog-shape);
82
83
  min-width: 17.5rem;
@@ -139,7 +140,6 @@
139
140
  animation: opacity var(--m3-util-easing-fast) 50ms both;
140
141
  }
141
142
  dialog[open] .buttons {
142
- position: relative;
143
143
  animation:
144
144
  buttonsIn var(--m3-util-curve-decel) 500ms,
145
145
  opacity var(--m3-util-easing-fast) 100ms both;
@@ -160,9 +160,11 @@
160
160
  }
161
161
  @keyframes buttonsIn {
162
162
  0% {
163
+ position: relative;
163
164
  bottom: 100%;
164
165
  }
165
166
  100% {
167
+ position: relative;
166
168
  bottom: 0;
167
169
  }
168
170
  }
@@ -99,7 +99,9 @@
99
99
  left: 0.75rem;
100
100
  top: 1rem;
101
101
  color: rgb(var(--error, var(--m3-scheme-on-surface-variant)));
102
- background-color: rgb(var(--m3-util-background, var(--m3-scheme-surface)));
102
+ background-color: rgb(
103
+ var(--m3-util-background, var(--m3-scheme-surface))
104
+ ); /* TODO: next breaking change, make --m3-util-background a full color and update the comment above */
103
105
  padding: 0 0.25rem;
104
106
  pointer-events: none;
105
107
  transition:
@@ -88,7 +88,9 @@
88
88
  left: 0.75rem;
89
89
  top: 1rem;
90
90
  color: rgb(var(--error, var(--m3-scheme-on-surface-variant)));
91
- background-color: rgb(var(--m3-util-background, var(--m3-scheme-surface)));
91
+ background-color: rgb(
92
+ var(--m3-util-background, var(--m3-scheme-surface))
93
+ ); /* TODO: next breaking change, make --m3-util-background a full color and update the comment above */
92
94
  padding: 0 0.25rem;
93
95
  pointer-events: none;
94
96
  transition:
@@ -49,3 +49,4 @@ export { default as VariableTabsLink } from "./nav/VariableTabsLink.svelte";
49
49
  export { default as ChipChooser } from "./utils/ChipChooser.svelte";
50
50
  export { default as Divider } from "./utils/Divider.svelte";
51
51
  export { default as DateField } from "./utils/DateField.svelte";
52
+ export { default as DateFieldOutlined } from "./utils/DateFieldOutlined.svelte";
package/package/index.js CHANGED
@@ -48,3 +48,4 @@ export { default as VariableTabsLink } from "./nav/VariableTabsLink.svelte";
48
48
  export { default as ChipChooser } from "./utils/ChipChooser.svelte";
49
49
  export { default as Divider } from "./utils/Divider.svelte";
50
50
  export { default as DateField } from "./utils/DateField.svelte";
51
+ export { default as DateFieldOutlined } from "./utils/DateFieldOutlined.svelte";
@@ -14,12 +14,14 @@
14
14
  date = $bindable(""),
15
15
  required = false,
16
16
  disabled = false,
17
+ error = false,
17
18
  ...extra
18
19
  }: {
19
20
  label: string;
20
21
  date?: string;
21
22
  required?: boolean;
22
23
  disabled?: boolean;
24
+ error?: boolean;
23
25
  } & HTMLInputAttributes = $props();
24
26
 
25
27
  const id = $props.id();
@@ -56,10 +58,10 @@ opacity: ${Math.min(t * 3, 1)};`,
56
58
  let label = $derived(_label || extra.name); // TODO: next breaking version, drop name backsupport
57
59
  </script>
58
60
 
59
- <div class="m3-container" class:has-js={hasJs} class:disabled use:clickOutside>
61
+ <div class="m3-container" class:has-js={hasJs} class:disabled class:error use:clickOutside>
60
62
  <input
61
63
  type="date"
62
- class="m3-font-body-large"
64
+ class="focus-none m3-font-body-large"
63
65
  {disabled}
64
66
  {required}
65
67
  {id}
@@ -69,7 +71,7 @@ opacity: ${Math.min(t * 3, 1)};`,
69
71
  <label class="m3-font-body-small" for={id}>{label}</label>
70
72
  <button type="button" {disabled} onclick={() => (picker = !picker)}>
71
73
  <Layer />
72
- <Icon icon={iconCalendar} />
74
+ <Icon icon={iconCalendar} width="1.5rem" height="1.5rem" />
73
75
  </button>
74
76
  {#if picker}
75
77
  <div class="picker" transition:enterExit>
@@ -93,7 +95,7 @@ opacity: ${Math.min(t * 3, 1)};`,
93
95
  min-width: 15rem;
94
96
  background-color: rgb(var(--m3-scheme-surface-container-highest));
95
97
  border-radius: var(--m3-datefield-shape) var(--m3-datefield-shape) 0 0;
96
- border-bottom: solid 1px rgb(var(--m3-scheme-on-surface-variant));
98
+ border-bottom: solid 1px rgb(var(--error, var(--m3-scheme-on-surface-variant)));
97
99
  }
98
100
  input {
99
101
  position: absolute;
@@ -110,7 +112,7 @@ opacity: ${Math.min(t * 3, 1)};`,
110
112
  position: absolute;
111
113
  left: 1rem;
112
114
  top: 0.5rem;
113
- color: rgb(var(--m3-scheme-on-surface-variant));
115
+ color: rgb(var(--error, var(--m3-scheme-on-surface-variant)));
114
116
  pointer-events: none;
115
117
  }
116
118
  input {
@@ -153,10 +155,10 @@ opacity: ${Math.min(t * 3, 1)};`,
153
155
  cursor: auto;
154
156
  }
155
157
 
156
- button > :global(svg) {
157
- width: 1.5rem;
158
- height: 1.5rem;
158
+ .error {
159
+ --error: var(--m3-scheme-error);
159
160
  }
161
+
160
162
  .picker {
161
163
  position: absolute;
162
164
  top: calc(100% + 1rem);
@@ -4,6 +4,7 @@ type $$ComponentProps = {
4
4
  date?: string;
5
5
  required?: boolean;
6
6
  disabled?: boolean;
7
+ error?: boolean;
7
8
  } & HTMLInputAttributes;
8
9
  declare const DateField: import("svelte").Component<$$ComponentProps, {}, "date">;
9
10
  type DateField = ReturnType<typeof DateField>;
@@ -0,0 +1,226 @@
1
+ <script lang="ts">
2
+ import { onMount } from "svelte";
3
+ import type { HTMLInputAttributes } from "svelte/elements";
4
+ import type { TransitionConfig } from "svelte/transition";
5
+ import iconCalendar from "@ktibow/iconset-material-symbols/calendar-today-outline";
6
+ import Icon from "../misc/_icon.svelte";
7
+ import Layer from "../misc/Layer.svelte";
8
+
9
+ import DatePickerDocked from "../forms/DatePickerDocked.svelte";
10
+ import { easeEmphasized } from "../misc/easing";
11
+
12
+ let {
13
+ label: _label,
14
+ date = $bindable(""),
15
+ required = false,
16
+ disabled = false,
17
+ error = false,
18
+ ...extra
19
+ }: {
20
+ label: string;
21
+ date?: string;
22
+ required?: boolean;
23
+ disabled?: boolean;
24
+ error?: boolean;
25
+ } & HTMLInputAttributes = $props();
26
+
27
+ const id = $props.id();
28
+ let hasJs = $state(false);
29
+ onMount(() => {
30
+ hasJs = true;
31
+ });
32
+
33
+ let picker = $state(false);
34
+ const clickOutside = (container: Node) => {
35
+ const handleClick = (event: Event) => {
36
+ if (!container.contains(event.target as Node)) {
37
+ picker = false;
38
+ }
39
+ };
40
+ document.addEventListener("click", handleClick, true);
41
+ return {
42
+ destroy() {
43
+ document.removeEventListener("click", handleClick, true);
44
+ },
45
+ };
46
+ };
47
+ const enterExit = (_: Node): TransitionConfig => {
48
+ return {
49
+ duration: 400,
50
+ easing: easeEmphasized,
51
+ css: (t, u) => `clip-path: inset(-100% 0 ${u * 100}% 0 round 1rem);
52
+ transform-origin: top;
53
+ transform: scaleY(${(t * 0.3 + 0.7) * 100}%);
54
+ opacity: ${Math.min(t * 3, 1)};`,
55
+ };
56
+ };
57
+
58
+ let label = $derived(_label || extra.name); // TODO: next breaking version, drop name backsupport
59
+ </script>
60
+
61
+ <div class="m3-container" class:has-js={hasJs} class:disabled class:error use:clickOutside>
62
+ <input
63
+ type="date"
64
+ class="focus-none m3-font-body-large"
65
+ {disabled}
66
+ {required}
67
+ {id}
68
+ bind:value={date}
69
+ {...extra}
70
+ />
71
+ <div class="layer"></div>
72
+ <label class="m3-font-body-small" for={id}>{label}</label>
73
+ <button type="button" {disabled} onclick={() => (picker = !picker)}>
74
+ <Layer />
75
+ <Icon icon={iconCalendar} width="1.5rem" height="1.5rem" />
76
+ </button>
77
+ {#if picker}
78
+ <div class="picker" transition:enterExit>
79
+ <DatePickerDocked
80
+ {date}
81
+ clearable={!required}
82
+ close={() => (picker = false)}
83
+ setDate={(d) => (date = d)}
84
+ />
85
+ </div>
86
+ {/if}
87
+ </div>
88
+
89
+ <style>
90
+ /*
91
+ want to customize the label's background?
92
+ do this: <DateFieldOutlined --m3-util-background="var(--m3-scheme-surface-container)" />
93
+ */
94
+ :root {
95
+ --m3-datefield-outlined-shape: var(--m3-util-rounding-extra-small);
96
+ }
97
+ .m3-container {
98
+ display: inline-flex;
99
+ position: relative;
100
+ height: 3.5rem;
101
+ min-width: 15rem;
102
+ }
103
+ input {
104
+ position: absolute;
105
+ inset: 0;
106
+ width: 100%;
107
+ height: 100%;
108
+ border: none;
109
+ outline: none;
110
+ padding: 1rem;
111
+ border-radius: var(--m3-datefield-outlined-shape);
112
+ background-color: transparent;
113
+ color: rgb(var(--m3-scheme-on-surface));
114
+ }
115
+ label {
116
+ position: absolute;
117
+ left: 0.75rem;
118
+ top: calc(var(--m3-font-body-small-height, 1rem) * -0.5);
119
+ color: rgb(var(--error, var(--m3-scheme-on-surface-variant)));
120
+ background-color: rgb(
121
+ var(--m3-util-background, var(--m3-scheme-surface))
122
+ ); /* TODO: next breaking change, make --m3-util-background a full color and update the comment above */
123
+ padding: 0 0.25rem;
124
+ pointer-events: none;
125
+ transition: all 200ms;
126
+ }
127
+ .layer {
128
+ position: absolute;
129
+ inset: 0;
130
+ border: 1px solid rgb(var(--error, var(--m3-scheme-outline)));
131
+ border-radius: var(--m3-datefield-outlined-shape);
132
+ pointer-events: none;
133
+ transition: all 200ms;
134
+ }
135
+
136
+ button {
137
+ display: none;
138
+ position: absolute;
139
+ width: 3.5rem;
140
+ height: 100%;
141
+ right: 0;
142
+
143
+ align-items: center;
144
+ justify-content: center;
145
+ border: none;
146
+ background-color: transparent;
147
+ color: rgb(var(--m3-scheme-on-surface-variant));
148
+ border-top-right-radius: var(--m3-datefield-outlined-shape);
149
+
150
+ -webkit-tap-highlight-color: transparent;
151
+ cursor: pointer;
152
+ }
153
+
154
+ input {
155
+ padding-left: 0.875rem;
156
+ }
157
+ @supports (-moz-appearance: none) {
158
+ input {
159
+ padding-left: 0.75rem;
160
+ }
161
+ }
162
+
163
+ input:hover ~ label {
164
+ color: rgb(var(--error, var(--m3-scheme-on-surface)));
165
+ }
166
+ input:hover ~ .layer {
167
+ border-color: rgb(var(--error, var(--m3-scheme-on-surface)));
168
+ }
169
+ input:focus ~ label {
170
+ color: rgb(var(--error, var(--m3-scheme-primary)));
171
+ }
172
+ input:focus ~ .layer {
173
+ border-color: rgb(var(--error, var(--m3-scheme-primary)));
174
+ border-width: 0.125rem;
175
+ }
176
+ @media (hover: hover) {
177
+ button:hover {
178
+ background-color: rgb(var(--m3-scheme-on-surface-variant) / 0.08);
179
+ }
180
+ }
181
+ button:focus-visible,
182
+ button:active {
183
+ background-color: rgb(var(--m3-scheme-on-surface-variant) / 0.12);
184
+ }
185
+
186
+ .error {
187
+ --error: var(--m3-scheme-error);
188
+ }
189
+ .error > input:hover ~ label,
190
+ .error > input:hover ~ .layer {
191
+ --error: var(--m3-scheme-on-error-container);
192
+ }
193
+
194
+ .m3-container.disabled {
195
+ opacity: 0.38;
196
+ }
197
+ input:disabled {
198
+ color: rgb(var(--m3-scheme-on-surface) / 0.38);
199
+ }
200
+ input:disabled ~ label {
201
+ color: rgb(var(--m3-scheme-on-surface) / 0.38);
202
+ }
203
+ input:disabled ~ .layer {
204
+ border-color: rgb(var(--m3-scheme-on-surface) / 0.38);
205
+ }
206
+ button:disabled {
207
+ color: rgb(var(--m3-scheme-on-surface-variant) / 0.38);
208
+ cursor: auto;
209
+ }
210
+
211
+ .picker {
212
+ position: absolute;
213
+ top: calc(100% + 1rem);
214
+ right: 0;
215
+ z-index: 1;
216
+ }
217
+
218
+ @media (min-width: 37.5rem) {
219
+ .has-js button {
220
+ display: flex;
221
+ }
222
+ .has-js input {
223
+ clip-path: inset(0 3.5rem 0 0);
224
+ }
225
+ }
226
+ </style>
@@ -0,0 +1,11 @@
1
+ import type { HTMLInputAttributes } from "svelte/elements";
2
+ type $$ComponentProps = {
3
+ label: string;
4
+ date?: string;
5
+ required?: boolean;
6
+ disabled?: boolean;
7
+ error?: boolean;
8
+ } & HTMLInputAttributes;
9
+ declare const DateFieldOutlined: import("svelte").Component<$$ComponentProps, {}, "date">;
10
+ type DateFieldOutlined = ReturnType<typeof DateFieldOutlined>;
11
+ export default DateFieldOutlined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "m3-svelte",
3
- "version": "4.5.6",
3
+ "version": "4.6.0",
4
4
  "license": "Apache-2.0 OR GPL-3.0-only",
5
5
  "repository": "KTibow/m3-svelte",
6
6
  "author": {