m3-svelte 4.5.7 → 4.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -131,19 +131,18 @@
131
131
  pointer-events: auto;
132
132
  animation:
133
133
  dialogIn var(--m3-util-curve-decel) 500ms,
134
- opacity var(--m3-util-curve-decel) 100ms both;
134
+ opacity var(--m3-util-curve-decel) 100ms backwards;
135
135
  }
136
136
  dialog[open] .headline {
137
137
  animation: opacity var(--m3-util-easing-fast);
138
138
  }
139
139
  dialog[open] .content {
140
- animation: opacity var(--m3-util-easing-fast) 50ms both;
140
+ animation: opacity var(--m3-util-easing-fast) 50ms backwards;
141
141
  }
142
142
  dialog[open] .buttons {
143
- position: relative;
144
143
  animation:
145
144
  buttonsIn var(--m3-util-curve-decel) 500ms,
146
- opacity var(--m3-util-easing-fast) 100ms both;
145
+ opacity var(--m3-util-easing-fast) 100ms backwards;
147
146
  }
148
147
  dialog::backdrop {
149
148
  background-color: rgb(var(--m3-scheme-scrim) / 0.3);
@@ -161,9 +160,11 @@
161
160
  }
162
161
  @keyframes buttonsIn {
163
162
  0% {
163
+ position: relative;
164
164
  bottom: 100%;
165
165
  }
166
166
  100% {
167
+ position: relative;
167
168
  bottom: 0;
168
169
  }
169
170
  }
@@ -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.7",
3
+ "version": "4.6.1",
4
4
  "license": "Apache-2.0 OR GPL-3.0-only",
5
5
  "repository": "KTibow/m3-svelte",
6
6
  "author": {