srcdev-nuxt-forms 2.4.11 → 2.4.12

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.
@@ -3,7 +3,7 @@
3
3
  class="input-text-wrapper"
4
4
  :data-form-theme="formTheme"
5
5
  :data-size="size"
6
- :class="[{ dirty: isDirty }, { active: isActive }, { error: fieldHasError }, { 'has-left-slot': hasLeftSlot }, { 'has-right-slot': hasRightSlot }]"
6
+ :class="[{ isMaterial: isMaterial }, { dirty: isDirty }, { active: isActive }, { error: fieldHasError }, { 'has-left-slot': hasLeftSlot }, { 'has-right-slot': hasRightSlot }]"
7
7
  >
8
8
  <span v-if="hasLeftSlot" class="slot left-slot">
9
9
  <slot name="left"></slot>
@@ -98,8 +98,14 @@ const props = defineProps({
98
98
  return propValidators.size.includes(value);
99
99
  },
100
100
  },
101
+ isMaterial: {
102
+ type: Boolean,
103
+ default: false,
104
+ },
101
105
  });
102
106
 
107
+ console.log('isMaterial: ', props.isMaterial);
108
+
103
109
  const slots = useSlots();
104
110
  const hasLeftSlot = computed(() => slots.left !== undefined);
105
111
  const hasRightSlot = computed(() => slots.right !== undefined);
@@ -250,6 +256,23 @@ onMounted(() => {
250
256
  border-left: 2px solid var(--theme-btn-bg-hover);
251
257
  }
252
258
  }
259
+
260
+ /* Material Design Styles */
261
+
262
+ &.isMaterial {
263
+ background-color: transparent;
264
+ border-radius: initial;
265
+ border: none;
266
+ outline: none;
267
+ box-shadow: none;
268
+ opacity: 0;
269
+ transition: opacity 0.2s ease-in-out;
270
+
271
+ &.active,
272
+ &.dirty {
273
+ opacity: 1;
274
+ }
275
+ }
253
276
  }
254
277
 
255
278
  input:autofill,
@@ -1,5 +1,20 @@
1
1
  <template>
2
- <InputTextWithLabel v-model="modelValue" :data-form-theme="formTheme" :type="inputType" :maxlength :name :placeholder :label :errorMessage :fieldHasError :required :styleClassPassthrough :theme>
2
+ <InputTextWithLabel
3
+ v-model="modelValue"
4
+ :data-form-theme="formTheme"
5
+ :type="inputType"
6
+ :maxlength
7
+ :name
8
+ :placeholder
9
+ :label
10
+ :errorMessage
11
+ :fieldHasError
12
+ :required
13
+ :styleClassPassthrough
14
+ :theme
15
+ :size
16
+ :isMaterial
17
+ >
3
18
  <template #right>
4
19
  <InputButtonCore
5
20
  type="button"
@@ -25,7 +40,7 @@ import propValidators from '../../c12/prop-validators';
25
40
 
26
41
  const props = defineProps({
27
42
  type: {
28
- type: String,
43
+ type: String as PropType<'text' | 'password'>,
29
44
  default: 'password',
30
45
  },
31
46
  maxlength: {
@@ -74,6 +89,10 @@ const props = defineProps({
74
89
  return propValidators.size.includes(value);
75
90
  },
76
91
  },
92
+ isMaterial: {
93
+ type: Boolean,
94
+ default: false,
95
+ },
77
96
  });
78
97
 
79
98
  const formTheme = computed(() => {
@@ -89,7 +108,7 @@ const updateFocus = (name: string, isFocused: boolean) => {
89
108
  // modelValue.value.focusedField = isFocused ? name : '';
90
109
  };
91
110
 
92
- const inputType = ref(props.type);
111
+ const inputType = ref<'text' | 'password'>(props.type);
93
112
 
94
113
  const displayPassword = ref(false);
95
114
  const buttonText = computed(() => {
@@ -24,6 +24,7 @@
24
24
  inputmode="numeric"
25
25
  :ariaDescribedby
26
26
  :size
27
+ :isMaterial
27
28
  >
28
29
  <template v-if="hasLeftSlot" #left>
29
30
  <InputButtonCore
@@ -121,6 +122,10 @@ const props = defineProps({
121
122
  return propValidators.size.includes(value);
122
123
  },
123
124
  },
125
+ isMaterial: {
126
+ type: Boolean,
127
+ default: false,
128
+ },
124
129
  });
125
130
 
126
131
  const slots = useSlots();
@@ -1,38 +1,46 @@
1
1
  <template>
2
- <div class="input-text-with-label" :data-form-theme="formTheme" :class="[elementClasses, { dirty: isDirty }, { active: isActive }]">
3
- <label :for="id" class="input-text-label body-normal-bold">{{ label }}</label>
2
+ <div>
3
+ <div class="input-text-with-label" :data-form-theme="formTheme" :class="[elementClasses, { isMaterial: isMaterial }, { dirty: isDirty }, { active: isActive }]">
4
+ <label :for="id" class="input-text-label">{{ label }}</label>
4
5
 
5
- <div v-if="hasDescriptionSlot" :id="`${id}-description`">
6
- <slot name="description"></slot>
6
+ <div v-if="!isMaterial && hasDescriptionSlot" :id="`${id}-description`">
7
+ <slot name="description"></slot>
8
+ </div>
9
+
10
+ <InputTextCore
11
+ v-model="modelValue"
12
+ v-model:isDirty="isDirty"
13
+ v-model:isActive="isActive"
14
+ :type
15
+ :inputmode
16
+ :maxlength
17
+ :id
18
+ :name
19
+ :placeholder
20
+ :label
21
+ :errorMessage
22
+ :fieldHasError
23
+ :required
24
+ :styleClassPassthrough
25
+ :theme
26
+ :ariaDescribedby
27
+ :size
28
+ :isMaterial
29
+ >
30
+ <template v-if="hasLeftSlot" #left>
31
+ <slot name="left"></slot>
32
+ </template>
33
+ <template v-if="hasRightSlot" #right>
34
+ <slot name="right"></slot>
35
+ </template>
36
+ </InputTextCore>
37
+
38
+ <InputError :errorMessage="errorMessage" :showError="fieldHasError" :id="errorId" :isDetached="false" />
7
39
  </div>
8
40
 
9
- <InputTextCore
10
- v-model="modelValue"
11
- v-model:isDirty="isDirty"
12
- v-model:isActive="isActive"
13
- :type
14
- :inputmode
15
- :maxlength
16
- :id
17
- :name
18
- :placeholder
19
- :label
20
- :errorMessage
21
- :fieldHasError
22
- :required
23
- :styleClassPassthrough
24
- :theme
25
- :ariaDescribedby
26
- :size
27
- >
28
- <template v-if="hasLeftSlot" #left>
29
- <slot name="left"></slot>
30
- </template>
31
- <template v-if="hasRightSlot" #right>
32
- <slot name="right"></slot>
33
- </template>
34
- </InputTextCore>
35
- <InputError :errorMessage="errorMessage" :showError="fieldHasError" :id="errorId" :isDetached="false" />
41
+ <div v-if="isMaterial && hasDescriptionSlot" :id="`${id}-description`">
42
+ <slot name="description"></slot>
43
+ </div>
36
44
  </div>
37
45
  </template>
38
46
 
@@ -44,7 +52,7 @@ const props = defineProps({
44
52
  default: 255,
45
53
  },
46
54
  type: {
47
- type: String,
55
+ type: String as PropType<'text' | 'email' | 'password' | 'number' | 'tel' | 'url'>,
48
56
  required: true,
49
57
  },
50
58
  inputmode: {
@@ -96,6 +104,10 @@ const props = defineProps({
96
104
  return propValidators.size.includes(value);
97
105
  },
98
106
  },
107
+ isMaterial: {
108
+ type: Boolean,
109
+ default: false,
110
+ },
99
111
  });
100
112
 
101
113
  const slots = useSlots();
@@ -142,9 +154,62 @@ watch(
142
154
 
143
155
  <style lang="css">
144
156
  .input-text-with-label {
157
+ --_focus-box-shadow: var(--box-shadow-off);
158
+
145
159
  .input-text-label {
146
160
  display: block;
147
161
  margin-block: 0.8rem;
162
+ font-size: var(--step-1);
163
+ font-weight: normal;
164
+ line-height: 1.5;
165
+ }
166
+
167
+ /* Material Design Styles */
168
+
169
+ &.isMaterial {
170
+ --_label-offset: 0 0;
171
+
172
+ display: grid;
173
+ grid-template-columns: 1fr;
174
+ grid-template-rows: 1fr;
175
+ grid-template-areas: 'material-text-stack';
176
+
177
+ background-color: var(--theme-form-input-bg);
178
+ border-radius: var(--form-element-border-width);
179
+ border: var(--form-element-border-width) solid var(--theme-form-input-border);
180
+ outline: var(--form-element-outline-width) solid var(--theme-form-input-outline);
181
+ box-shadow: var(--_focus-box-shadow);
182
+
183
+ padding: 0 0.8rem;
184
+
185
+ .input-text-label {
186
+ grid-area: material-text-stack;
187
+
188
+ display: inline-block;
189
+ width: fit-content;
190
+ padding: 0.2rem 1.2rem;
191
+ background-color: var(--theme-form-input-bg);
192
+ border-radius: 0.4em;
193
+ color: var(--theme-form-input-text);
194
+ translate: var(--_label-offset);
195
+
196
+ font-size: var(--step-2);
197
+ font-weight: normal;
198
+ line-height: 1.5;
199
+
200
+ transition: font-size 0.2s ease-in-out, translate 0.2s ease-in-out;
201
+
202
+ &:has(+ .input-text-wrapper.active),
203
+ &:has(+ .input-text-wrapper.dirty) {
204
+ --_label-offset: 0 -3rem;
205
+ /* font-size: var(--step-2); */
206
+ /* padding: 0.2rem 1.2rem; */
207
+ }
208
+ }
209
+
210
+ .input-text-wrapper {
211
+ grid-area: material-text-stack;
212
+ }
148
213
  }
149
214
  }
150
215
  </style>
@@ -1,24 +1,6 @@
1
1
  export const useColourScheme = () => {
2
- // const currentColourScheme = computed(() => {
3
- // return colourScheme.value;
4
- // });
5
-
6
2
  const currentColourScheme = ref<'auto' | 'dark' | 'light' | null>(null);
7
3
 
8
- // const updateColourScheme = (newColourScheme: 'auto' | 'dark' | 'light') => {
9
- // colourScheme.value = newColourScheme;
10
- // };
11
-
12
- // const getSetPrefereredColourScheme = () => {
13
- // if (import.meta.client) {
14
- // if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches && !document.documentElement.dataset.colorScheme) {
15
- // colourScheme.value = 'dark';
16
- // } else {
17
- // colourScheme.value = 'light';
18
- // }
19
- // }
20
- // };
21
-
22
4
  const returnSavedColourPreferenceFromLocalStorage = () => {
23
5
  if (import.meta.client) {
24
6
  return localStorage.getItem('colourScheme') as 'auto' | 'dark' | 'light' | null;
@@ -27,18 +9,6 @@ export const useColourScheme = () => {
27
9
 
28
10
  onMounted(() => {
29
11
  currentColourScheme.value = returnSavedColourPreferenceFromLocalStorage() || 'auto';
30
- // colourScheme.value = currentColourScheme.value;
31
- //
32
- // if (import.meta.client) {
33
- // const savedColourScheme = localStorage.getItem('colourScheme');
34
- // if (savedColourScheme) {
35
- // colourScheme.value = savedColourScheme as 'dark' | 'light';
36
- // } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
37
- // colourScheme.value = 'dark';
38
- // } else {
39
- // colourScheme.value = 'light';
40
- // }
41
- // }
42
12
  });
43
13
 
44
14
  watch(currentColourScheme, (newVal) => {
@@ -51,8 +21,5 @@ export const useColourScheme = () => {
51
21
 
52
22
  return {
53
23
  currentColourScheme,
54
- // colourScheme,
55
- // updateColourScheme,
56
- // getSetPrefereredColourScheme,
57
24
  };
58
25
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-forms",
3
3
  "type": "module",
4
- "version": "2.4.11",
4
+ "version": "2.4.12",
5
5
  "main": "nuxt.config.ts",
6
6
  "scripts": {
7
7
  "clean": "rm -rf .nuxt && rm -rf .output && rm -rf .playground/.nuxt && rm -rf .playground/.output",