@iroco/ui 1.14.18 → 1.15.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.
@@ -199,7 +199,7 @@
199
199
  left: 0;
200
200
  height: 1em;
201
201
  width: 1em;
202
- background-color: var(--form-element-bg);
202
+ background-color: var(--color-background);
203
203
  border-radius: 50%;
204
204
  border: 1px solid;
205
205
  }
@@ -0,0 +1,33 @@
1
+ <script module lang="ts">
2
+ import { PasswordInput } from './index';
3
+
4
+ import { defineMeta, setTemplate } from '@storybook/addon-svelte-csf';
5
+
6
+ const { Story } = defineMeta({
7
+ title: 'Iroco-UI/Form/PasswordInput',
8
+ component: PasswordInput,
9
+ argTypes: {
10
+ type: { control: { type: 'select' } },
11
+ autocomplete: { control: { type: 'select' } }
12
+ }
13
+ });
14
+
15
+ let oninputFoo = $state<string | null>('');
16
+
17
+ function handleOnInput(event: Event & { currentTarget: EventTarget & HTMLInputElement }) {
18
+ oninputFoo = '' + event.data + ' ' + event.timeStamp;
19
+ }
20
+ </script>
21
+
22
+ <script lang="ts">
23
+ setTemplate(template);
24
+ </script>
25
+
26
+ {#snippet template({ ...args })}
27
+ <form class="iroco-ui-form">
28
+ <PasswordInput {...args} oninput={handleOnInput} />
29
+ </form>
30
+ <p>On input handled : {oninputFoo}</p>
31
+ {/snippet}
32
+
33
+ <Story name="Default" />
@@ -0,0 +1,19 @@
1
+ import { PasswordInput } from './index';
2
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const PasswordInput: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
16
+ [evt: string]: CustomEvent<any>;
17
+ }, {}, {}, string>;
18
+ type PasswordInput = InstanceType<typeof PasswordInput>;
19
+ export default PasswordInput;
@@ -0,0 +1,294 @@
1
+ <script lang="ts">
2
+ import type { FormEventHandler, HTMLInputAttributes } from 'svelte/elements';
3
+ import { eye } from 'svelte-awesome/icons';
4
+ import { Icon } from 'svelte-awesome';
5
+
6
+ export type ValidationErrorMessage = { key: string; isHtml?: boolean };
7
+
8
+ interface Props extends HTMLInputAttributes {
9
+ id?: string | null;
10
+ name?: string | null;
11
+ label?: string | null;
12
+ placeholder?: string | null;
13
+ error?: string | null;
14
+ errors?: Array<ValidationErrorMessage> | null;
15
+ htmlError?: boolean;
16
+ value?: string | null;
17
+ onfocus?: ((e: FocusEvent) => void) | null;
18
+ onblur?: ((e: Event) => void) | null;
19
+ readonly?: boolean;
20
+ border?: boolean;
21
+ oninput?: FormEventHandler<HTMLInputElement> | null | undefined;
22
+ }
23
+
24
+ let {
25
+ id = null,
26
+ name = null,
27
+ label = null,
28
+ placeholder = null,
29
+ error = null,
30
+ errors = [],
31
+ htmlError = false,
32
+ value = $bindable(null),
33
+ onfocus = null,
34
+ onblur = null,
35
+ readonly = false,
36
+ border = false,
37
+ autocomplete = 'on',
38
+ oninput,
39
+ ...rest
40
+ }: Props = $props();
41
+
42
+ let showPassword = $state(false);
43
+ let fieldType: 'password' | 'text' = $derived(showPassword ? 'text' : 'password');
44
+
45
+ function toggleShowPassword() {
46
+ showPassword = !showPassword;
47
+ }
48
+
49
+ function hasErrors() {
50
+ return error !== null || (errors?.length ?? 0) > 0;
51
+ }
52
+ </script>
53
+
54
+ <div class="iroco-ui-input">
55
+ {#if label}
56
+ <label class="iroco-ui-label" for={id}>{label}</label>
57
+ {/if}
58
+ <input
59
+ type={fieldType}
60
+ {oninput}
61
+ bind:value
62
+ {onfocus}
63
+ {onblur}
64
+ {id}
65
+ {name}
66
+ {placeholder}
67
+ {autocomplete}
68
+ class:border
69
+ class:error={hasErrors()}
70
+ class:readonlyInput={readonly === true}
71
+ {readonly}
72
+ {...rest}
73
+ />
74
+ <button class="password-viewer" type="button" onclick={toggleShowPassword}>
75
+ <Icon data={eye} />
76
+ </button>
77
+ {#if error != null}
78
+ <p data-testid="error" class="error">
79
+ {#if htmlError}
80
+ {@html error !== null ? error : ''}
81
+ {:else}
82
+ {error !== null ? error : ''}
83
+ {/if}
84
+ </p>
85
+ {/if}
86
+ </div>
87
+
88
+ <style>:root {
89
+ --color-beige: #f2ebe3;
90
+ --color-light-beige: #fff9f4;
91
+ --color-dark-beige: #eaddd5;
92
+ --color-dark-grey: #33323a;
93
+ --color-medium-grey: #464452;
94
+ --color-medium-light-grey: #a9a29e;
95
+ --color-light-grey: #f5f5f5;
96
+ --color-dark-blue: #211d28;
97
+ --color-dark-blue-op-30: #211d284d;
98
+ --color-night-blue: #18151e;
99
+ --color-black: black;
100
+ --color-white: white;
101
+ --color-red: #ff504d;
102
+ --color-green: #00d692;
103
+ --color-light-green: #82eec7;
104
+ --color-dark-green: #00704e;
105
+ --color-yellow: #ffe032;
106
+ --color-blue: #001fcd;
107
+ /* Caution !!! Hover doesn't work with --color-white-op-20: rgba(var(--color-white), 0.2)); */
108
+ --color-white-op-20: rgba(255, 255, 255, 0.2);
109
+ --color-white-op-30: rgba(255, 255, 255, 0.3);
110
+ --color-black-op-20: rgba(0, 0, 0, 0.2);
111
+ --color-black-op-40: rgba(0, 0, 0, 0.4);
112
+ --color-black-op-60: rgba(0, 0, 0, 0.6);
113
+ --color-red-op-80: rgba(var(--color-red), 0.8);
114
+ --color-green-op-80: rgba(var(--color-green), 0.8);
115
+ --color-yellow-op-80: rgba(var(--color-yellow), 0.8);
116
+ /* global colors */
117
+ /* border */
118
+ /* body */
119
+ }
120
+ @media (prefers-color-scheme: dark) {
121
+ :root {
122
+ --color-background: var(--color-dark-blue);
123
+ --color-background-darker: var(--color-night-blue);
124
+ --color-background-grey: var(--color-dark-grey);
125
+ --color-foreground: var(--color-beige);
126
+ --color-link: var(--color-green);
127
+ --color-highlight: var(--color-yellow);
128
+ }
129
+ }
130
+ @media (prefers-color-scheme: light) {
131
+ :root {
132
+ --color-background: var(--color-light-beige);
133
+ --color-background-darker: var(--color-dark-beige);
134
+ --color-background-grey: var(--color-light-grey);
135
+ --color-foreground: var(--color-black);
136
+ --color-link: var(--color-dark-green);
137
+ --color-highlight: var(--color-blue);
138
+ }
139
+ }
140
+ @media (prefers-contrast: more) {
141
+ :root {
142
+ --color-background: var(--color-white);
143
+ --color-background-darker: var(--color-dark-beige);
144
+ --color-background-grey: var(--color-light-grey);
145
+ --color-foreground: var(--color-black);
146
+ --color-link: var(--color-dark-green);
147
+ --color-highlight: var(--color-blue);
148
+ }
149
+ }
150
+ :root {
151
+ /* semantic colors */
152
+ --color-primary-light: var(--color-light-green);
153
+ --color-primary: var(--color-green);
154
+ --color-secondary: var(--color-beige);
155
+ /* feedback */
156
+ --color-success: var(--color-green);
157
+ --color-success-bg: var(--color-green-op-80);
158
+ --color-danger: var(--color-red);
159
+ --color-danger-bg: var(--color-red-op-80);
160
+ --color-warning: var(--color-yellow);
161
+ --color-warning-bg: var(--color-yellow-op-80);
162
+ /* typography */
163
+ --color-text: var(--color-foreground);
164
+ --color-text-dark: var(--color-medium-grey);
165
+ --color-text-op-80: rgba(var(--color-text), 0.8);
166
+ --color-text-op-99: rgba(var(--color-text), 0.99);
167
+ }
168
+ @media (prefers-color-scheme: dark) {
169
+ :root {
170
+ --color-border: var(--color-medium-grey);
171
+ }
172
+ }
173
+ @media (prefers-color-scheme: light) {
174
+ :root {
175
+ --color-border: var(--color-medium-light-grey);
176
+ }
177
+ }
178
+ :root {
179
+ --color-body: var(--color-background);
180
+ }
181
+
182
+ .iroco-ui-form {
183
+ --form-element-border: var(--color-foreground);
184
+ --form-element-bg: var(--color-foreground);
185
+ --form-text-placeholder: var(--color-medium-grey);
186
+ }
187
+ .iroco-ui-form input,
188
+ .iroco-ui-form textarea {
189
+ outline-color: var(--color-border);
190
+ outline-style: ridge;
191
+ text-decoration: none;
192
+ font-size: 14px;
193
+ }
194
+ .iroco-ui-form input:focus,
195
+ .iroco-ui-form textarea:focus {
196
+ outline-color: var(--color-primary);
197
+ outline-style: auto;
198
+ }
199
+ .iroco-ui-form .iroco-ui-input {
200
+ display: flex;
201
+ flex-direction: column;
202
+ }
203
+ .iroco-ui-form .iroco-ui-input > input {
204
+ color: var(--color-text);
205
+ background: var(--color-body);
206
+ border: 1px solid var(--color-border);
207
+ padding: 1em 1.5em;
208
+ text-overflow: ellipsis;
209
+ white-space: nowrap;
210
+ overflow: hidden;
211
+ border-radius: 0.5em;
212
+ }
213
+ .iroco-ui-form .iroco-ui-input > input::placeholder {
214
+ color: var(--form-text-placeholder);
215
+ }
216
+ .iroco-ui-form .iroco-ui-input > input.error {
217
+ border-color: var(--color-danger);
218
+ }
219
+ .iroco-ui-form .iroco-ui-input > input.error:focus {
220
+ outline-color: var(--color-danger);
221
+ }
222
+ .iroco-ui-form .iroco-ui-input > input.readonlyInput {
223
+ cursor: not-allowed;
224
+ }
225
+ .iroco-ui-form .iroco-ui-input > input.border {
226
+ border: 1px solid var(--form-element-border);
227
+ }
228
+ .iroco-ui-form .iroco-ui-label {
229
+ color: var(--color-text-op-99);
230
+ font-weight: bold;
231
+ padding-bottom: 10px;
232
+ display: inline-block;
233
+ }
234
+ .iroco-ui-form p.error {
235
+ margin: 0;
236
+ color: var(--color-danger);
237
+ }
238
+
239
+ /* radio button */
240
+ .iroco-ui-radio {
241
+ color: var(--color-text);
242
+ position: relative;
243
+ margin-top: 0.5em;
244
+ padding-left: 1.5em;
245
+ cursor: pointer;
246
+ -webkit-user-select: none;
247
+ -moz-user-select: none;
248
+ -ms-user-select: none;
249
+ user-select: none;
250
+ }
251
+
252
+ .iroco-ui-radio input {
253
+ position: absolute;
254
+ opacity: 0;
255
+ cursor: pointer;
256
+ }
257
+ .iroco-ui-radio input:focus + .radio-button-color {
258
+ outline-color: var(--color-primary);
259
+ outline-style: auto;
260
+ }
261
+
262
+ .radio-button-color {
263
+ position: absolute;
264
+ top: 0;
265
+ left: 0;
266
+ height: 1em;
267
+ width: 1em;
268
+ background-color: var(--color-background);
269
+ border-radius: 50%;
270
+ border: 1px solid;
271
+ }
272
+
273
+ .iroco-ui-radio input:checked ~ .radio-button-color {
274
+ background-color: var(--color-primary);
275
+ }
276
+
277
+ .iroco-ui-input {
278
+ position: relative;
279
+ width: 100%;
280
+ }
281
+ .iroco-ui-input input {
282
+ width: 100%;
283
+ padding-right: 35px;
284
+ }
285
+ .iroco-ui-input .password-viewer {
286
+ position: absolute;
287
+ right: 10px;
288
+ top: 50%;
289
+ transform: translateY(-50%);
290
+ cursor: pointer;
291
+ color: var(--color-background);
292
+ background-color: transparent;
293
+ border: none;
294
+ }</style>
@@ -0,0 +1,23 @@
1
+ import type { FormEventHandler, HTMLInputAttributes } from 'svelte/elements';
2
+ export type ValidationErrorMessage = {
3
+ key: string;
4
+ isHtml?: boolean;
5
+ };
6
+ interface Props extends HTMLInputAttributes {
7
+ id?: string | null;
8
+ name?: string | null;
9
+ label?: string | null;
10
+ placeholder?: string | null;
11
+ error?: string | null;
12
+ errors?: Array<ValidationErrorMessage> | null;
13
+ htmlError?: boolean;
14
+ value?: string | null;
15
+ onfocus?: ((e: FocusEvent) => void) | null;
16
+ onblur?: ((e: Event) => void) | null;
17
+ readonly?: boolean;
18
+ border?: boolean;
19
+ oninput?: FormEventHandler<HTMLInputElement> | null | undefined;
20
+ }
21
+ declare const PasswordInput: import("svelte").Component<Props, {}, "value">;
22
+ type PasswordInput = ReturnType<typeof PasswordInput>;
23
+ export default PasswordInput;
@@ -195,7 +195,7 @@
195
195
  left: 0;
196
196
  height: 1em;
197
197
  width: 1em;
198
- background-color: var(--form-element-bg);
198
+ background-color: var(--color-background);
199
199
  border-radius: 50%;
200
200
  border: 1px solid;
201
201
  }
@@ -257,7 +257,7 @@
257
257
  left: 0;
258
258
  height: 1em;
259
259
  width: 1em;
260
- background-color: var(--form-element-bg);
260
+ background-color: var(--color-background);
261
261
  border-radius: 50%;
262
262
  border: 1px solid;
263
263
  }
package/dist/index.d.ts CHANGED
@@ -19,5 +19,6 @@ export { default as NumberInput } from './NumberInput.svelte';
19
19
  export { default as RadioButton } from './RadioButton.svelte';
20
20
  export { default as SlottedComponentWrapper } from './SlottedComponentWrapper.svelte';
21
21
  export { default as TextInput } from './TextInput.svelte';
22
+ export { default as PasswordInput } from './PasswordInput.svelte';
22
23
  export { Steps } from './svelte-steps';
23
24
  export * from './definition';
package/dist/index.js CHANGED
@@ -19,5 +19,6 @@ export { default as NumberInput } from './NumberInput.svelte';
19
19
  export { default as RadioButton } from './RadioButton.svelte';
20
20
  export { default as SlottedComponentWrapper } from './SlottedComponentWrapper.svelte';
21
21
  export { default as TextInput } from './TextInput.svelte';
22
+ export { default as PasswordInput } from './PasswordInput.svelte';
22
23
  export { Steps } from './svelte-steps';
23
24
  export * from './definition';
@@ -95,7 +95,7 @@
95
95
  left: 0;
96
96
  height: 1em;
97
97
  width: 1em;
98
- background-color: var(--form-element-bg);
98
+ background-color: var(--color-background);
99
99
  border-radius: 50%;
100
100
  border: 1px solid;
101
101
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iroco/ui",
3
- "version": "1.14.18",
3
+ "version": "1.15.0",
4
4
  "description": "Iroco design system based on Svelte",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {