@geoffcox/sterling-svelte 0.0.17 → 0.0.18

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.
package/Checkbox.svelte CHANGED
@@ -2,7 +2,12 @@
2
2
  import Label from "./Label.svelte";
3
3
  export let checked = false;
4
4
  export let disabled = false;
5
- const inputId = uuid();
5
+ export let id = void 0;
6
+ $: {
7
+ if ($$slots.default && id === void 0) {
8
+ id = uuid();
9
+ }
10
+ }
6
11
  </script>
7
12
 
8
13
  <!--
@@ -12,6 +17,8 @@ const inputId = uuid();
12
17
  <div class="sterling-checkbox">
13
18
  <div class="container">
14
19
  <input
20
+ {disabled}
21
+ {id}
15
22
  type="checkbox"
16
23
  on:blur
17
24
  on:click
@@ -35,15 +42,13 @@ const inputId = uuid();
35
42
  on:wheel
36
43
  bind:checked
37
44
  {...$$restProps}
38
- id={inputId}
39
- {disabled}
40
45
  />
41
46
  <div class="indicator" />
42
47
  </div>
43
- {#if $$slots.label}
48
+ {#if $$slots.default}
44
49
  <div class="label">
45
- <Label {disabled} for={inputId}>
46
- <slot name="label" {checked} {disabled} />
50
+ <Label {disabled} for={id}>
51
+ <slot {checked} {disabled} />
47
52
  </Label>
48
53
  </div>
49
54
  {/if}
@@ -4,6 +4,7 @@ declare const __propDef: {
4
4
  [x: string]: any;
5
5
  checked?: boolean | undefined;
6
6
  disabled?: boolean | undefined;
7
+ id?: string | undefined;
7
8
  };
8
9
  events: {
9
10
  blur: FocusEvent;
@@ -30,7 +31,7 @@ declare const __propDef: {
30
31
  [evt: string]: CustomEvent<any>;
31
32
  };
32
33
  slots: {
33
- label: {
34
+ default: {
34
35
  checked: boolean;
35
36
  disabled: boolean;
36
37
  };
package/Field.svelte ADDED
@@ -0,0 +1,257 @@
1
+ <script>import { createKeyborg } from "keyborg";
2
+ import { onMount } from "svelte";
3
+ import Tooltip from "./Tooltip.svelte";
4
+ export let forwardClick = false;
5
+ let htmlFor = void 0;
6
+ export { htmlFor as for };
7
+ export let label = void 0;
8
+ export let message = void 0;
9
+ export let required = false;
10
+ export let requiredTip = "This field is required";
11
+ export let status = "none";
12
+ let fieldRef;
13
+ let targetDisabled = false;
14
+ let targetRef = null;
15
+ const findTarget = () => {
16
+ let candidate = null;
17
+ if (htmlFor) {
18
+ candidate = fieldRef?.querySelector(`[id="${htmlFor}"]`);
19
+ }
20
+ if (!candidate) {
21
+ candidate = fieldRef?.querySelector(
22
+ 'a[href], audio[controls], button, details, div[contenteditable], form, input, select, textarea, video[controls], [tabindex]:not([tabindex="-1"])'
23
+ );
24
+ }
25
+ targetRef = candidate;
26
+ };
27
+ const isElementDisabled = (element) => {
28
+ if (element) {
29
+ return element.getAttribute("aria-disabled") === "true" || element?.matches(":disabled") || element?.disabled === true || element?.classList.contains("disabled");
30
+ }
31
+ return false;
32
+ };
33
+ $:
34
+ $$slots.default, fieldRef, htmlFor, findTarget();
35
+ $: {
36
+ targetDisabled = isElementDisabled(targetRef);
37
+ }
38
+ const mutationCallback = (mutations) => {
39
+ let disabled = void 0;
40
+ for (let i = 0; i < mutations.length; i++) {
41
+ const mutation = mutations[i];
42
+ if (mutation.type === "attributes") {
43
+ if (mutation.attributeName === "aria-disabled" || mutation.attributeName === "disabled" || mutation.attributeName === "class") {
44
+ if (isElementDisabled(targetRef)) {
45
+ disabled = true;
46
+ break;
47
+ }
48
+ disabled = false;
49
+ }
50
+ }
51
+ }
52
+ if (disabled !== void 0) {
53
+ targetDisabled = disabled;
54
+ }
55
+ };
56
+ let mutationObserver = new MutationObserver(mutationCallback);
57
+ $: {
58
+ mutationObserver.disconnect();
59
+ if (targetRef) {
60
+ mutationObserver.observe(targetRef, {
61
+ attributes: true
62
+ });
63
+ }
64
+ }
65
+ let keyborg = createKeyborg(window);
66
+ let usingKeyboard = keyborg.isNavigatingWithKeyboard();
67
+ const keyborgHandler = (value) => {
68
+ usingKeyboard = value;
69
+ };
70
+ onMount(() => {
71
+ keyborg.subscribe(keyborgHandler);
72
+ return () => {
73
+ keyborg.unsubscribe(keyborgHandler);
74
+ };
75
+ });
76
+ const onClick = () => {
77
+ if (forwardClick) {
78
+ targetRef?.click();
79
+ }
80
+ };
81
+ </script>
82
+
83
+ <label
84
+ aria-disabled={targetDisabled}
85
+ bind:this={fieldRef}
86
+ class="sterling-field"
87
+ class:disabled={targetDisabled}
88
+ class:using-keyboard={usingKeyboard}
89
+ for={htmlFor}
90
+ on:blur
91
+ on:click
92
+ on:click={onClick}
93
+ on:copy
94
+ on:cut
95
+ on:dblclick
96
+ on:focus
97
+ on:focusin
98
+ on:focusout
99
+ on:keydown
100
+ on:keypress
101
+ on:keyup
102
+ on:mousedown
103
+ on:mouseenter
104
+ on:mouseleave
105
+ on:mousemove
106
+ on:mouseover
107
+ on:mouseout
108
+ on:mouseup
109
+ on:scroll
110
+ on:wheel
111
+ on:paste
112
+ {...$$restProps}
113
+ >
114
+ <slot name="label" disabled={targetDisabled} for={htmlFor} {label} {required}>
115
+ <div class="label-text">
116
+ {label}
117
+ </div>
118
+ </slot>
119
+ <slot />
120
+ {#if message}
121
+ <slot name="message" disabled={targetDisabled} {message} {required} {status}>
122
+ <div
123
+ class="message"
124
+ class:info={status === 'info'}
125
+ class:success={status === 'success'}
126
+ class:warning={status === 'warning'}
127
+ class:error={status === 'error'}
128
+ >
129
+ {message}
130
+ </div>
131
+ </slot>
132
+ {/if}
133
+ {#if required}
134
+ <slot name="required" {requiredTip}>
135
+ <Tooltip autoShow="hover">
136
+ <span class="required-tip" slot="tip">{requiredTip}</span>
137
+ <div class="required">*</div>
138
+ </Tooltip>
139
+ </slot>
140
+ {/if}
141
+ </label>
142
+
143
+ <style>
144
+ .sterling-field {
145
+ background-color: var(--stsv-Input__background-color);
146
+ border-color: var(--stsv-Input__border-color);
147
+ border-radius: var(--stsv-Input__border-radius);
148
+ border-style: var(--stsv-Input__border-style);
149
+ border-width: var(--stsv-Input__border-width);
150
+ box-sizing: border-box;
151
+ color: var(--stsv-Input__color);
152
+ display: flex;
153
+ flex-direction: column;
154
+ font: inherit;
155
+ margin: 0;
156
+ overflow: visible;
157
+ padding: 0;
158
+ position: relative;
159
+ transition: background-color 250ms, color 250ms, border-color 250ms;
160
+ }
161
+
162
+ .sterling-field:hover {
163
+ background-color: var(--stsv-Input__background-color--hover);
164
+ border-color: var(--stsv-Input__border-color--hover);
165
+ color: var(--stsv-Input__color--hover);
166
+ }
167
+
168
+ .sterling-field.using-keyboard:focus-within {
169
+ border-color: var(--stsv-Common__border-color--focus);
170
+ color: var(--stsv-Common__color--focus);
171
+ outline-color: var(--stsv-Common__outline-color);
172
+ outline-offset: var(--stsv-Common__outline-offset);
173
+ outline-style: var(--stsv-Common__outline-style);
174
+ outline-width: var(--stsv-Common__outline-width);
175
+ }
176
+
177
+ .sterling-field.disabled {
178
+ background-color: var(--stsv-Common__background-color--disabled);
179
+ border-color: var(--stsv--Common__border-color--disabled);
180
+ color: var(--stsv-Common__color--disabled);
181
+ }
182
+
183
+ .label-text {
184
+ color: var(--stsv-Display__color);
185
+ font-size: 0.8em;
186
+ margin: 0.5em 0.7em 0.2em 0.2em;
187
+ }
188
+
189
+ .label-text:empty {
190
+ margin: 0;
191
+ }
192
+
193
+ .sterling-field.disabled .label-text {
194
+ color: var(--stsv-Common__color--disabled);
195
+ }
196
+
197
+ .message {
198
+ font-size: 0.8em;
199
+ background-color: var(--stsv-Display__background-color);
200
+ color: var(--stsv-Display__color);
201
+ padding: 0.5em;
202
+ transition: background-color 250ms, color 250ms, border-color 250ms;
203
+ }
204
+
205
+ .message.info {
206
+ background-color: var(--stsv-Info__background-color);
207
+ border-color: var(--stsv-Info__border-color);
208
+ color: var(--stsv-Info__color);
209
+ }
210
+
211
+ .message.success {
212
+ background-color: var(--stsv-Success__background-color);
213
+ border-color: var(--stsv-Success__border-color);
214
+ color: var(--stsv-Success__color);
215
+ }
216
+
217
+ .message.warning {
218
+ background-color: var(--stsv-Warning__background-color);
219
+ border-color: var(--stsv-Warning__border-color);
220
+ color: var(--stsv-Warning__color);
221
+ }
222
+
223
+ .message.error {
224
+ background-color: var(--stsv-Error__background-color);
225
+ border-color: var(--stsv__Error-color);
226
+ color: var(--stsv-Error__color);
227
+ }
228
+
229
+ .sterling-field.disabled .message {
230
+ background-color: var(--stsv-Common__background-color--disabled);
231
+ border-color: var(--stsv--Common__border-color--disabled);
232
+ color: var(--stsv-Common__color--disabled);
233
+ }
234
+
235
+ .required {
236
+ text-align: center;
237
+ font-weight: bold;
238
+ box-sizing: border-box;
239
+ width: 1em;
240
+ height: 1em;
241
+ position: absolute;
242
+ top: 0;
243
+ right: 0;
244
+ }
245
+
246
+ .required-tip {
247
+ display: block;
248
+ padding: 4px;
249
+ }
250
+
251
+ @media (prefers-reduced-motion) {
252
+ .sterling-field,
253
+ .message {
254
+ transition: none;
255
+ }
256
+ }
257
+ </style>
@@ -0,0 +1,63 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type { FieldStatus } from './Field.types';
3
+ declare const __propDef: {
4
+ props: {
5
+ [x: string]: any;
6
+ forwardClick?: boolean | undefined;
7
+ for?: string | undefined;
8
+ label?: string | undefined;
9
+ message?: string | undefined;
10
+ required?: boolean | undefined;
11
+ requiredTip?: string | undefined;
12
+ status?: FieldStatus | undefined;
13
+ };
14
+ events: {
15
+ blur: FocusEvent;
16
+ click: MouseEvent;
17
+ copy: ClipboardEvent;
18
+ cut: ClipboardEvent;
19
+ dblclick: MouseEvent;
20
+ focus: FocusEvent;
21
+ focusin: FocusEvent;
22
+ focusout: FocusEvent;
23
+ keydown: KeyboardEvent;
24
+ keypress: KeyboardEvent;
25
+ keyup: KeyboardEvent;
26
+ mousedown: MouseEvent;
27
+ mouseenter: MouseEvent;
28
+ mouseleave: MouseEvent;
29
+ mousemove: MouseEvent;
30
+ mouseover: MouseEvent;
31
+ mouseout: MouseEvent;
32
+ mouseup: MouseEvent;
33
+ scroll: Event;
34
+ wheel: WheelEvent;
35
+ paste: ClipboardEvent;
36
+ } & {
37
+ [evt: string]: CustomEvent<any>;
38
+ };
39
+ slots: {
40
+ label: {
41
+ disabled: boolean;
42
+ for: string | undefined;
43
+ label: string | undefined;
44
+ required: boolean;
45
+ };
46
+ default: {};
47
+ message: {
48
+ disabled: boolean;
49
+ message: string | undefined;
50
+ required: boolean;
51
+ status: FieldStatus;
52
+ };
53
+ required: {
54
+ requiredTip: string;
55
+ };
56
+ };
57
+ };
58
+ export type FieldProps = typeof __propDef.props;
59
+ export type FieldEvents = typeof __propDef.events;
60
+ export type FieldSlots = typeof __propDef.slots;
61
+ export default class Field extends SvelteComponentTyped<FieldProps, FieldEvents, FieldSlots> {
62
+ }
63
+ export {};
@@ -0,0 +1 @@
1
+ export type FieldStatus = 'none' | 'info' | 'success' | 'warning' | 'error';
package/Field.types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/Input.svelte CHANGED
@@ -1,58 +1,58 @@
1
1
  <script>import { v4 as uuid } from "uuid";
2
2
  import Label from "./Label.svelte";
3
- export let value = "";
3
+ export let composed = false;
4
4
  export let disabled = false;
5
- const inputId = uuid();
5
+ export let id = void 0;
6
+ export let value = "";
7
+ $: {
8
+ if ($$slots.default && id === void 0) {
9
+ id = uuid();
10
+ }
11
+ }
6
12
  </script>
7
13
 
8
- <!--
9
- @component
10
- A styled HTML input element with optional label.
11
- -->
12
- <div class="sterling-input">
13
- {#if $$slots.label}
14
- <Label {disabled} for={inputId}>
15
- <slot name="label" />
16
- </Label>
17
- {/if}
18
- <input
19
- bind:value
20
- on:blur
21
- on:click
22
- on:change
23
- on:copy
24
- on:cut
25
- on:paste
26
- on:dblclick
27
- on:focus
28
- on:focusin
29
- on:focusout
30
- on:input
31
- on:invalid
32
- on:keydown
33
- on:keypress
34
- on:keyup
35
- on:mousedown
36
- on:mouseenter
37
- on:mouseleave
38
- on:mousemove
39
- on:mouseover
40
- on:mouseout
41
- on:mouseup
42
- on:select
43
- on:submit
44
- on:reset
45
- on:wheel
46
- {...$$restProps}
47
- {disabled}
48
- id={inputId}
49
- />
50
- </div>
14
+ {#if $$slots.default}
15
+ <Label {disabled} for={id}>
16
+ <slot {composed} {disabled} {value} />
17
+ </Label>
18
+ {/if}
19
+ <input
20
+ bind:value
21
+ class="sterling-input"
22
+ class:composed
23
+ {disabled}
24
+ {id}
25
+ on:blur
26
+ on:click
27
+ on:change
28
+ on:copy
29
+ on:cut
30
+ on:paste
31
+ on:dblclick
32
+ on:focus
33
+ on:focusin
34
+ on:focusout
35
+ on:input
36
+ on:invalid
37
+ on:keydown
38
+ on:keypress
39
+ on:keyup
40
+ on:mousedown
41
+ on:mouseenter
42
+ on:mouseleave
43
+ on:mousemove
44
+ on:mouseover
45
+ on:mouseout
46
+ on:mouseup
47
+ on:select
48
+ on:submit
49
+ on:reset
50
+ on:wheel
51
+ {...$$restProps}
52
+ />
51
53
 
52
54
  <style>
53
55
  .sterling-input {
54
- display: flex;
55
- flex-direction: column;
56
56
  background-color: var(--stsv-Input__background-color);
57
57
  border-color: var(--stsv-Input__border-color);
58
58
  border-radius: var(--stsv-Input__border-radius);
@@ -61,6 +61,8 @@ const inputId = uuid();
61
61
  color: var(--stsv-Input__color);
62
62
  font: inherit;
63
63
  margin: 0;
64
+ outline: none;
65
+ padding: 0.5em;
64
66
  transition: background-color 250ms, color 250ms, border-color 250ms;
65
67
  }
66
68
 
@@ -70,7 +72,7 @@ const inputId = uuid();
70
72
  color: var(--stsv-Input__color--hover);
71
73
  }
72
74
 
73
- .sterling-input:focus-within {
75
+ .sterling-input:focus {
74
76
  background-color: var(--stsv-Input__background-color--focus);
75
77
  border-color: var(--stsv-Input__border-color--focus);
76
78
  color: var(--stsv-Input__color--focus);
@@ -87,42 +89,26 @@ const inputId = uuid();
87
89
  cursor: not-allowed;
88
90
  }
89
91
 
90
- .sterling-input input {
91
- font: inherit;
92
- color: inherit;
93
- padding: 0.5em;
94
- }
95
-
96
- .sterling-input input,
97
- .sterling-input input:hover,
98
- .sterling-input input:focus-within,
99
- .sterling-input input:disabled {
100
- background-color: transparent;
92
+ .sterling-input.composed,
93
+ .sterling-input.composed:hover,
94
+ .sterling-input.composed:focus,
95
+ .sterling-input.composed.disabled {
96
+ background: transparent;
101
97
  border: none;
102
98
  outline: none;
103
99
  }
104
100
 
105
- .sterling-input input::placeholder {
101
+ .sterling-input::placeholder {
106
102
  color: var(--stsv-Display__color--faint);
107
103
  transition: background-color 250ms, color 250ms, border-color 250ms;
108
104
  }
109
105
 
110
- .sterling-input input:disabled::placeholder {
106
+ .sterling-input:disabled::placeholder {
111
107
  color: var(--stsv-Display__color--disabled);
112
108
  }
113
109
 
114
- .sterling-input > :global(label) {
115
- font-size: 0.7em;
116
- margin: 0.5em 0 0 0.7em;
117
- }
118
-
119
- .sterling-input > :global(label):empty {
120
- margin: 0;
121
- }
122
-
123
110
  @media (prefers-reduced-motion) {
124
- .sterling-input,
125
- .sterling-input input::placeholder {
111
+ .sterling-input {
126
112
  transition: none;
127
113
  }
128
114
  }
package/Input.svelte.d.ts CHANGED
@@ -2,8 +2,10 @@ import { SvelteComponentTyped } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
4
  [x: string]: any;
5
- value?: string | undefined;
5
+ composed?: boolean | undefined;
6
6
  disabled?: boolean | undefined;
7
+ id?: string | undefined;
8
+ value?: string | undefined;
7
9
  };
8
10
  events: {
9
11
  blur: FocusEvent;
@@ -36,13 +38,16 @@ declare const __propDef: {
36
38
  [evt: string]: CustomEvent<any>;
37
39
  };
38
40
  slots: {
39
- label: {};
41
+ default: {
42
+ composed: boolean;
43
+ disabled: boolean;
44
+ value: string;
45
+ };
40
46
  };
41
47
  };
42
48
  export type InputProps = typeof __propDef.props;
43
49
  export type InputEvents = typeof __propDef.events;
44
50
  export type InputSlots = typeof __propDef.slots;
45
- /** A styled HTML input element with optional label. */
46
51
  export default class Input extends SvelteComponentTyped<InputProps, InputEvents, InputSlots> {
47
52
  }
48
53
  export {};
package/Label.svelte CHANGED
@@ -1,7 +1,9 @@
1
1
  <script>export let disabled = false;
2
+ HTMLLabelElement;
2
3
  </script>
3
4
 
4
5
  <label
6
+ aria-disabled={disabled}
5
7
  class="sterling-label"
6
8
  class:disabled
7
9
  on:blur
@@ -30,18 +32,15 @@
30
32
  <slot />
31
33
  </label>
32
34
 
33
- <!--
34
- @component
35
- A styled HTML label element
36
- -->
37
35
  <style>
38
36
  label {
39
- transition: opacity 250ms;
37
+ color: var(--stsv-Display__color);
38
+ transition: color 250ms;
40
39
  font: inherit;
41
40
  }
42
41
 
43
42
  label.disabled {
44
- opacity: 0.5;
43
+ color: var(--stsv-Common__color--disabled);
45
44
  }
46
45
 
47
46
  @media (prefers-reduced-motion) {
package/Label.svelte.d.ts CHANGED
@@ -36,7 +36,6 @@ declare const __propDef: {
36
36
  export type LabelProps = typeof __propDef.props;
37
37
  export type LabelEvents = typeof __propDef.events;
38
38
  export type LabelSlots = typeof __propDef.slots;
39
- /** A styled HTML label element */
40
39
  export default class Label extends SvelteComponentTyped<LabelProps, LabelEvents, LabelSlots> {
41
40
  }
42
41
  export {};